예제 #1
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            //LastUpdated = DateTime.Now;
            if (!hasConnected && amConnecting)
            {
                return;
            }

            if (!hasConnected)
            {
                amConnecting = true;
                try
                {
                    Connect(new ConnectAnnounceState(parameters, ConnectAnnounceCallback, state));
                }
                catch (SocketException)
                {
                    DoAnnounceComplete(false, state, new List <Peer>());
                    return;
                }
            }
            else
            {
                DoAnnounce(parameters, state);
            }
        }
예제 #2
0
        public void MultipleAnnounce()
        {
            int              announceCount = 0;
            Random           r             = new Random();
            ManualResetEvent handle        = new ManualResetEvent(false);

            for (int i = 0; i < 20; i++)
            {
                InfoHash infoHash = new InfoHash(new byte[20]);
                r.NextBytes(infoHash.Hash);
                TrackerTier tier = new TrackerTier(new string[] { uri.ToString() });
                tier.Trackers[0].AnnounceComplete += delegate {
                    if (++announceCount == 20)
                    {
                        handle.Set();
                    }
                };
                TrackerConnectionID id = new TrackerConnectionID(tier.Trackers[0], false, TorrentEvent.Started, new ManualResetEvent(false));
                MonoTorrent.Client.Tracker.AnnounceParameters parameters;
                parameters = new MonoTorrent.Client.Tracker.AnnounceParameters(0, 0, 0, TorrentEvent.Started,
                                                                               infoHash, false, new string('1', 20), "", 1411);
                tier.Trackers[0].Announce(parameters, id);
            }

            Assert.IsTrue(handle.WaitOne(5000, true), "Some of the responses weren't received");
        }
예제 #3
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            //LastUpdated = DateTime.Now;
               if (!hasConnected && amConnecting)
               {
               	   		IAsyncResult ar = ReceiveAsyncResult;
                if (ar != null)
                    if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2)))
                        return;
            }

               if (!hasConnected)
               {
               amConnecting = true;
               try
               {
                   Connect(new ConnectAnnounceState(parameters, ConnectAnnounceCallback, state));
               }
               catch (SocketException)
               {
                   DoAnnounceComplete(false, state, new List<Peer>());
                   return;
               }
               }
               else
               DoAnnounce(parameters, state);
        }
예제 #4
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            try
            {
                Uri            announceString = CreateAnnounceString(parameters);
                HttpWebRequest request        = (HttpWebRequest)HttpWebRequest.Create(announceString);
                request.UserAgent = MonoTorrent.Common.VersionInfo.ClientVersion;
                request.Proxy     = new WebProxy(); // If i don't do this, i can't run the webrequest. It's wierd.
                RaiseBeforeAnnounce();
                BeginRequest(request, AnnounceReceived, new object[] { request, state });
            }
            catch (Exception ex)
            {
                Status         = TrackerState.Offline;
                FailureMessage = ("Could not initiate announce request: " + ex.Message);
                RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, false));
            }

            if (state is TrackerConnectionID)
            {
                var id = ((TrackerConnectionID)state);
                if (id.WaitHandle != null)
                {
                    try
                    {
                        id.WaitHandle.Set();
                    }
                    catch
                    {
                    }
                }
            }
        }
예제 #5
0
        async Task <bool> Announce(TorrentEvent clientEvent, ITracker tracker)
        {
            var trackerTier = Tiers.First(t => t.Trackers.Contains(tracker));

            try {
                // If we have not announced to this Tracker tier yet then we should replace the ClientEvent.
                // But if we end up announcing to a different Tracker tier we may want to send the
                // original/unmodified args.
                AnnounceParameters actualArgs = RequestFactory.CreateAnnounce(clientEvent);
                if (!trackerTier.SentStartedEvent)
                {
                    actualArgs = actualArgs.WithClientEvent(TorrentEvent.Started);
                }

                List <Peer> peers = await tracker.AnnounceAsync(actualArgs);

                trackerTier.LastAnnounceSucceeded = true;

                trackerTier.ActiveTrackerIndex = trackerTier.Trackers.IndexOf(tracker);
                trackerTier.SentStartedEvent  |= actualArgs.ClientEvent == TorrentEvent.Started;
                trackerTier.LastAnnounce       = ValueStopwatch.StartNew();
                AnnounceComplete?.InvokeAsync(this, new AnnounceResponseEventArgs(tracker, true, peers.AsReadOnly()));
                return(true);
            } catch {
            }

            trackerTier.LastAnnounceSucceeded = false;
            AnnounceComplete?.InvokeAsync(this, new AnnounceResponseEventArgs(tracker, false));
            return(false);
        }
예제 #6
0
        public void Setup()
        {
            keys.Clear();

            listener.IncompleteAnnounce = listener.IncompleteScrape = false;

            server = new TrackerServer(trackerId)
            {
                AllowUnregisteredTorrents = true
            };
            server.RegisterListener(listener);

            tracker = (HTTPTracker)TrackerFactory.Create(AnnounceUrl);

            var infoHashBytes = new[] { ' ', '%', '&', '?', '&', '&', '?', '5', '1', '=' }
            .Select(t => (byte)t);

            infoHash       = new InfoHash(infoHashBytes.Concat(infoHashBytes).ToArray());
            announceParams = new AnnounceParameters()
                             .WithPort(5555)
                             .WithPeerId(peerId)
                             .WithInfoHash(infoHash);

            scrapeParams = new ScrapeParameters(new InfoHash(new byte[20]));
        }
예제 #7
0
        public async Task <List <Peer> > AnnounceAsync(AnnounceParameters parameters)
        {
            var result = await DoAnnounceAsync(parameters);

            LastAnnounced.Restart();
            return(result);
        }
예제 #8
0
        protected override async Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters)
        {
            // Clear out previous failure state
            FailureMessage = "";
            WarningMessage = "";
            var peers = new List <Peer>();

            try
            {
                var announceString = CreateAnnounceString(parameters);
                var request        = (HttpWebRequest)WebRequest.Create(announceString);
                request.UserAgent = VersionInfo.ClientVersion;
                request.Proxy     = new WebProxy(); // If i don't do this, i can't run the webrequest. It's wierd.

                using (CancellationTokenSource cts = new CancellationTokenSource(RequestTimeout))
                    using (cts.Token.Register(() => request.Abort()))
                        using (var response = await request.GetResponseAsync())
                            peers = AnnounceReceived(request, response);

                return(peers);
            }
            catch (Exception ex)
            {
                Status         = TrackerState.Offline;
                FailureMessage = "The tracker could not be contacted";
                throw new TrackerException(FailureMessage, ex);
            }
        }
예제 #9
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            //LastUpdated = DateTime.Now;
            if (!hasConnected && amConnecting)
            {
                IAsyncResult ar = ReceiveAsyncResult;
                if (ar != null)
                {
                    if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2)))
                    {
                        return;
                    }
                }
            }

            if (!hasConnected)
            {
                amConnecting = true;
                try
                {
                    Connect(new ConnectAnnounceState(parameters, ConnectAnnounceCallback, state));
                }
                catch (SocketException)
                {
                    DoAnnounceComplete(false, state, new List <Peer>());
                    return;
                }
            }
            else
            {
                DoAnnounce(parameters, state);
            }
        }
예제 #10
0
        protected override async Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters)
        {
            try {
                if (ConnectionIdTask == null || LastConnected.Elapsed > TimeSpan.FromMinutes(1))
                {
                    ConnectionIdTask = ConnectAsync();
                }
                long connectionId = await ConnectionIdTask;

                var message  = new AnnounceMessage(DateTime.Now.GetHashCode(), connectionId, parameters);
                var announce = (AnnounceResponseMessage) await SendAndReceiveAsync(message);

                MinUpdateInterval = announce.Interval;

                Status = TrackerState.Ok;
                return(announce.Peers);
            } catch (OperationCanceledException e) {
                Status           = TrackerState.Offline;
                ConnectionIdTask = null;
                throw new TrackerException("Announce could not be completed", e);
            } catch (Exception e) {
                Status           = TrackerState.InvalidResponse;
                ConnectionIdTask = null;
                throw new TrackerException("Announce could not be completed", e);
            }
        }
예제 #11
0
        async Task Announce(TorrentEvent clientEvent, ITracker referenceTracker)
        {
            // If the user initiates an Announce we need to go to the correct thread to process it.
            await ClientEngine.MainLoop;

            LastAnnounce.Restart();
            LastUpdated = DateTime.UtcNow;

            AnnounceParameters p = RequestFactory.CreateAnnounce(clientEvent);

            foreach ((TrackerTier trackerTier, ITracker tracker) in GetNextTracker(referenceTracker))
            {
                try {
                    // If we have not announced to this Tracker tier yet then we should replace the ClientEvent.
                    // But if we end up announcing to a different Tracker tier we may want to send the
                    // original/unmodified args.
                    AnnounceParameters actualArgs = p;
                    if (!trackerTier.SentStartedEvent)
                    {
                        actualArgs = actualArgs.WithClientEvent(TorrentEvent.Started);
                    }

                    List <Peer> peers = await tracker.AnnounceAsync(actualArgs);

                    LastAnnounceSucceeded = true;
                    AnnounceComplete?.InvokeAsync(this, new AnnounceResponseEventArgs(tracker, true, peers.AsReadOnly()));
                    return;
                } catch {
                }
            }

            LastAnnounceSucceeded = false;
            AnnounceComplete?.InvokeAsync(this, new AnnounceResponseEventArgs(null, false));
        }
예제 #12
0
        public void MultipleAnnounce()
        {
            var announceCount = 0;
            var r = new Random();
            var handle = new ManualResetEvent(false);

            for (var i = 0; i < 20; i++)
            {
                var infoHash = new InfoHash(new byte[20]);
                r.NextBytes(infoHash.Hash);
                var tier = new TrackerTier(new[] {uri.ToString()});
                tier.Trackers[0].AnnounceComplete += delegate
                {
                    if (++announceCount == 20)
                        handle.Set();
                };
                var id = new TrackerConnectionID(tier.Trackers[0], false, TorrentEvent.Started,
                    new ManualResetEvent(false));
                MonoTorrent.Client.Tracker.AnnounceParameters parameters;
                parameters = new MonoTorrent.Client.Tracker.AnnounceParameters(0, 0, 0, TorrentEvent.Started,
                    infoHash, false, new string('1', 20), "", 1411);
                tier.Trackers[0].Announce(parameters, id);
            }

            Assert.True(handle.WaitOne(5000, true), "Some of the responses weren't received");
        }
예제 #13
0
 public async ReusableTask <AnnounceResponse> AnnounceAsync(AnnounceParameters parameters, CancellationToken token)
 {
     try {
         return(await DoAnnounceAsync(parameters, token));
     } finally {
         LastAnnounced.Restart();
     }
 }
예제 #14
0
 public async void Announce(AnnounceParameters parameters, TrackerConnectionID state)
 {
     try {
         await AnnounceAsync(parameters, state);
     } catch {
         // Ignore
     }
 }
예제 #15
0
 private void DoAnnounce(AnnounceParameters parameters, object state)
 {
     var announceState = new ConnectAnnounceState(parameters, AnnounceCallback, state);
     announceState.Message = new AnnounceMessage(DateTime.Now.GetHashCode(), connectionId, parameters);
     try
     {
         SendAndReceive(announceState);
     }
     catch (SocketException)
     {
         DoAnnounceComplete(false, state, new List<Peer>());
     }
 }
예제 #16
0
        public async Task MultipleAnnounce()
        {
            Random r = new Random();

            for (int i = 0; i < 20; i++)
            {
                InfoHash infoHash = new InfoHash(new byte[20]);
                r.NextBytes(infoHash.Hash);
                TrackerTier tier       = new TrackerTier(new string[] { uri.ToString() });
                var         parameters = new MonoTorrent.Client.Tracker.AnnounceParameters(0, 0, 0, TorrentEvent.Started,
                                                                                           infoHash, false, new string('1', 20), "", 1411, false);
                await tier.Trackers[0].AnnounceAsync(parameters);
            }
        }
예제 #17
0
        private void DoAnnounce(AnnounceParameters parameters, object state)
        {
            ConnectAnnounceState announceState = new ConnectAnnounceState(parameters, AnnounceCallback, state);

            announceState.Message = new AnnounceMessage(DateTime.Now.GetHashCode(), connectionId, parameters);
            try
            {
                SendAndReceive(announceState);
            }
            catch (SocketException)
            {
                DoAnnounceComplete(false, state, new List <Peer>());
            }
        }
예제 #18
0
        public async ReusableTask AnnounceAsync(ITracker tracker, CancellationToken token)
        {
            Check.Tracker(tracker);

            // If the user initiates an Announce we need to go to the correct thread to process it.
            await ClientEngine.MainLoop;

            try {
                var trackerTier         = Tiers.First(t => t.Trackers.Contains(tracker));
                AnnounceParameters args = RequestFactory.CreateAnnounce(TorrentEvent.None);
                await AnnounceTrackerAsync(trackerTier, args, tracker, token);
            } catch {
            }
        }
예제 #19
0
        Uri CreateAnnounceString(AnnounceParameters parameters)
        {
            var b = new UriQueryBuilder(Uri);

            b.Add("info_hash", parameters.InfoHash.UrlEncode())
            .Add("peer_id", parameters.PeerId.UrlEncode())
            .Add("port", parameters.Port)
            .Add("uploaded", parameters.BytesUploaded)
            .Add("downloaded", parameters.BytesDownloaded)
            .Add("left", parameters.BytesLeft)
            .Add("compact", 1)
            .Add("numwant", 100);

            if (parameters.SupportsEncryption)
            {
                b.Add("supportcrypto", 1);
            }
            if (parameters.RequireEncryption)
            {
                b.Add("requirecrypto", 1);
            }
            if (!b.Contains("key") && Key != null)
            {
                b.Add("key", Key.UrlEncode());
            }
            if (!string.IsNullOrEmpty(parameters.IPAddress))
            {
                b.Add("ip", parameters.IPAddress);
            }

            // If we have not successfully sent the started event to this tier, override the passed in started event
            // Otherwise append the event if it is not "none"
            //if (!parameters.Id.Tracker.Tier.SentStartedEvent)
            //{
            //    sb.Append("&event=started");
            //    parameters.Id.Tracker.Tier.SendingStartedEvent = true;
            //}
            if (parameters.ClientEvent != TorrentEvent.None)
            {
                b.Add("event", parameters.ClientEvent.ToString().ToLower());
            }

            if (!BEncodedString.IsNullOrEmpty(TrackerId))
            {
                b.Add("trackerid", TrackerId.UrlEncode());
            }

            return(b.ToUri());
        }
예제 #20
0
        protected override async ReusableTask <AnnounceResponse> DoAnnounceAsync(AnnounceParameters parameters, CancellationToken token)
        {
            // WebRequest.Create can be a comparatively slow operation as reported
            // by profiling. Switch this to the threadpool so the querying of default
            // proxies, and any DNS requests, are definitely not run on the main thread.
            await MainLoop.SwitchToThreadpool();

            // Clear out previous failure state
            FailureMessage = "";
            WarningMessage = "";
            var peers = new List <Peer> ();

            Uri announceString = CreateAnnounceString(parameters);

            using var client = new HttpClient();
            client.DefaultRequestHeaders.Add("User-Agent", VersionInfo.ClientVersion);

            HttpResponseMessage response;

            // Ensure the supplied 'token' causes the request to be cancelled too.
            using var cts          = new CancellationTokenSource(RequestTimeout);
            using var registration = token.Register(cts.Cancel);

            try {
                Status   = TrackerState.Connecting;
                response = await client.GetAsync(announceString, HttpCompletionOption.ResponseHeadersRead, cts.Token);
            } catch (Exception ex) {
                Status         = TrackerState.Offline;
                FailureMessage = "The tracker could not be contacted";
                throw new TrackerException(FailureMessage, ex);
            }

            try {
                using var responseRegistration = cts.Token.Register(() => response.Dispose());
                using (response) {
                    peers = await AnnounceReceivedAsync(response).ConfigureAwait(false);

                    logger.InfoFormatted("Tracker {0} sent {1} peers", Uri, peers.Count);
                    Status = TrackerState.Ok;
                    return(new AnnounceResponse(peers, WarningMessage, FailureMessage));
                }
            } catch (Exception ex) {
                Status         = TrackerState.InvalidResponse;
                FailureMessage = "The tracker returned an invalid or incomplete response";
                throw new TrackerException(FailureMessage, ex);
            }
        }
예제 #21
0
        protected override async Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters)
        {
            // WebRequest.Create can be a comparatively slow operation as reported
            // by profiling. Switch this to the threadpool so the querying of default
            // proxies, and any DNS requests, are definitely not run on the main thread.
            await MainLoop.SwitchToThreadpool();

            // Clear out previous failure state
            FailureMessage = "";
            WarningMessage = "";
            var peers = new List <Peer> ();

            Uri announceString = CreateAnnounceString(parameters);
            var request        = (HttpWebRequest)WebRequest.Create(announceString);

            request.UserAgent = VersionInfo.ClientVersion;
            request.Proxy     = new WebProxy(); // If i don't do this, i can't run the webrequest. It's wierd.

            WebResponse response;

            using var cts = new CancellationTokenSource(RequestTimeout);
            using CancellationTokenRegistration registration = cts.Token.Register(() => request.Abort());

            try {
                Status   = TrackerState.Connecting;
                response = await request.GetResponseAsync().ConfigureAwait(false);
            } catch (Exception ex) {
                Status         = TrackerState.Offline;
                FailureMessage = "The tracker could not be contacted";
                throw new TrackerException(FailureMessage, ex);
            }

            try {
                using CancellationTokenRegistration responseRegistration = cts.Token.Register(() => response.Close());
                using (response) {
                    peers = await AnnounceReceivedAsync(response).ConfigureAwait(false);

                    Status = TrackerState.Ok;
                    return(peers);
                }
            } catch (Exception ex) {
                Status         = TrackerState.InvalidResponse;
                FailureMessage = "The tracker returned an invalid or incomplete response";
                throw new TrackerException(FailureMessage, ex);
            }
        }
예제 #22
0
        private async Task Announce(ITracker tracker, TorrentEvent clientEvent, bool trySubsequent)
        {
            ClientEngine engine = manager.Engine;

            // If the engine is null, we have been unregistered
            if (engine == null)
            {
                return;
            }

            this.updateSucceeded = true;
            this.lastUpdated     = DateTime.Now;

            EncryptionTypes e = engine.Settings.AllowedEncryption;
            bool            requireEncryption  = !Toolbox.HasEncryption(e, EncryptionTypes.PlainText);
            bool            supportsEncryption = Toolbox.HasEncryption(e, EncryptionTypes.RC4Full) || Toolbox.HasEncryption(e, EncryptionTypes.RC4Header);

            requireEncryption  = requireEncryption && ClientEngine.SupportsEncryption;
            supportsEncryption = supportsEncryption && ClientEngine.SupportsEncryption;

            IPEndPoint reportedAddress = engine.Settings.ReportedAddress;
            string     ip   = reportedAddress == null ? null : reportedAddress.Address.ToString();
            int        port = reportedAddress == null ? engine.Listener.Endpoint.Port : reportedAddress.Port;

            // FIXME: In metadata mode we need to pretend we need to download data otherwise
            // tracker optimisations might result in no peers being sent back.
            long bytesLeft = 1000;

            if (manager.HasMetadata)
            {
                bytesLeft = (long)((1 - this.manager.Bitfield.PercentComplete / 100.0) * this.manager.Torrent.Size);
            }
            AnnounceParameters p = new AnnounceParameters(this.manager.Monitor.DataBytesDownloaded,
                                                          this.manager.Monitor.DataBytesUploaded,
                                                          bytesLeft,
                                                          clientEvent, this.infoHash, requireEncryption, manager.Engine.PeerId,
                                                          ip, port);

            p.SupportsEncryption = supportsEncryption;
            try {
                var peers = await tracker.AnnounceAsync(p);
                await OnAnnounceComplete(tracker, peers, trySubsequent, clientEvent, true);
            } catch {
                await OnAnnounceComplete(tracker, new List <Peer>(), trySubsequent, clientEvent, false);
            }
        }
예제 #23
0
 public override void Announce(AnnounceParameters parameters, object state)
 {
     try
     {
         Uri announceString = CreateAnnounceString(parameters);
         HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(announceString);
         request.Proxy = new WebProxy();   // If i don't do this, i can't run the webrequest. It's wierd.
         RaiseBeforeAnnounce();
         BeginRequest(request, AnnounceReceived, new object[] { request, state });
     }
     catch (Exception ex)
     {
         Status = TrackerState.Offline;
         FailureMessage = ("Could not initiate announce request: " + ex.Message);
         RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, false));
     }
 }
        public AnnounceMessage(int transactionId, long connectionId, AnnounceParameters parameters)
            : base(1, transactionId)
        {
            ConnectionId = connectionId;
            if (parameters == null)
                return;

            Downloaded = parameters.BytesDownloaded;
            Infohash = parameters.InfoHash;
            Ip = 0;
            Key = (uint) DateTime.Now.GetHashCode(); // FIXME: Don't do this! It should be constant
            Left = parameters.BytesLeft;
            NumWanted = 50;
            PeerId = parameters.PeerId;
            Port = (ushort) parameters.Port;
            TorrentEvent = parameters.ClientEvent;
            Uploaded = parameters.BytesUploaded;
        }
예제 #25
0
        public AnnounceMessage(int transactionId, long connectionId, AnnounceParameters parameters)
            : base(1, transactionId)
        {
            this.connectionId = connectionId;
            if (parameters == null)
                return;

            downloaded = parameters.BytesDownloaded;
            infoHash = parameters.InfoHash;
            ip = 0;
            key = (uint) DateTime.Now.GetHashCode(); // FIXME: Don't do this! It should be constant
            left = parameters.BytesLeft;
            numWanted = 50;
            peerId = parameters.PeerId;
            port = (ushort) parameters.Port;
            torrentEvent = parameters.ClientEvent;
            uploaded = parameters.BytesUploaded;
        }
예제 #26
0
        public void AnnounceTest()
        {
            HTTPTracker t = (HTTPTracker)TrackerFactory.Create(new Uri(prefix));
            TrackerConnectionID id = new TrackerConnectionID(t, false, TorrentEvent.Started, new ManualResetEvent(false));

            AnnounceResponseEventArgs p = null;
            t.AnnounceComplete += delegate(object o, AnnounceResponseEventArgs e) {
                p = e;
                id.WaitHandle.Set();
            };
            MonoTorrent.Client.Tracker.AnnounceParameters pars = new AnnounceParameters();
            pars.Infohash = new byte[20];

            t.Announce(pars, id);
            Wait(id.WaitHandle);
            Assert.IsNotNull(p, "#1");
            Assert.IsTrue(p.Successful);
            Assert.AreEqual(keys[0], t.Key, "#2");
        }
예제 #27
0
        public override async Task AnnounceAsync(AnnounceParameters parameters, TrackerConnectionID state)
        {
            try {
                if (ConnectionIdTask == null || LastConnected.Elapsed > TimeSpan.FromMinutes(1))
                {
                    ConnectionIdTask = ConnectAsync();
                }
                await ConnectionIdTask;

                var message  = new AnnounceMessage(DateTime.Now.GetHashCode(), ConnectionIdTask.Result, parameters);
                var announce = (AnnounceResponseMessage) await SendAndReceiveAsync(message);

                MinUpdateInterval = announce.Interval;
                RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, true, announce.Peers));
            } catch (Exception e) {
                ConnectionIdTask = null;
                RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, false));
                throw new Exception("Announce could not be completed", e);
            }
        }
예제 #28
0
        protected override async Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters)
        {
            // WebRequest.Create can be a comparatively slow operation as reported
            // by profiling. Switch this to the threadpool so the querying of default
            // proxies, and any DNS requests, are definitely not run on the main thread.
            await MainLoop.SwitchToThreadpool();

            // Clear out previous failure state
            FailureMessage = "";
            WarningMessage = "";
            var peers = new List <Peer> ();

            Uri announceString = CreateAnnounceString(parameters);

            using var client = new HttpClient();
            HttpResponseMessage response;

            using var cts = new CancellationTokenSource(RequestTimeout);
            try {
                Status   = TrackerState.Connecting;
                response = await client.GetAsync(announceString, HttpCompletionOption.ResponseHeadersRead, cts.Token);
            } catch (Exception ex) {
                Status         = TrackerState.Offline;
                FailureMessage = "The tracker could not be contacted";
                throw new TrackerException(FailureMessage, ex);
            }

            try {
                using var responseRegistration = cts.Token.Register(() => response.Dispose());
                using (response) {
                    peers = await AnnounceReceivedAsync(response).ConfigureAwait(false);

                    Status = TrackerState.Ok;
                    return(peers);
                }
            } catch (Exception ex) {
                Status         = TrackerState.InvalidResponse;
                FailureMessage = "The tracker returned an invalid or incomplete response";
                throw new TrackerException(FailureMessage, ex);
            }
        }
예제 #29
0
        public override async Task AnnounceAsync(AnnounceParameters parameters, TrackerConnectionID state)
        {
            try
            {
                Uri            announceString = CreateAnnounceString(parameters);
                HttpWebRequest request        = (HttpWebRequest)HttpWebRequest.Create(announceString);
                request.UserAgent = MonoTorrent.Common.VersionInfo.ClientVersion;
                request.Proxy     = new WebProxy(); // If i don't do this, i can't run the webrequest. It's wierd.
                RaiseBeforeAnnounce();
                var response = await request.GetResponseAsync();

                AnnounceReceived(response, state);
            }
            catch (Exception ex)
            {
                Status         = TrackerState.Offline;
                FailureMessage = ("Could not initiate announce request: " + ex.Message);
                RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, false));
                throw;
            }
        }
예제 #30
0
        public async Task AnnounceTest()
        {
            announceparams = announceparams
                             .WithBytesDownloaded(123)
                             .WithBytesLeft(456)
                             .WithBytesUploaded(789);

            var announceArgsTask = new TaskCompletionSource <MonoTorrent.Tracker.AnnounceEventArgs> ();

            server.PeerAnnounced += (o, e) => announceArgsTask.TrySetResult(e);
            await tracker.AnnounceAsync(announceparams, CancellationToken.None);

            await announceArgsTask.Task;

            var args = announceArgsTask.Task.Result;

            Assert.AreEqual(PeerId, args.Peer.PeerId, "#1");
            Assert.AreEqual(123, args.Peer.Downloaded);
            Assert.AreEqual(456, args.Peer.Remaining);
            Assert.AreEqual(789, args.Peer.Uploaded);
        }
예제 #31
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            //LastUpdated = DateTime.Now;
            if (!hasConnected && amConnecting)
                return;

            if (!hasConnected)
            {
                amConnecting = true;
                try
                {
                    Connect(new ConnectAnnounceState(parameters, ConnectAnnounceCallback, state));
                }
                catch (SocketException)
                {
                    DoAnnounceComplete(false, state, new List<Peer>());
                }
            }
            else
                DoAnnounce(parameters, state);
        }
        private void OfflineAnnounceTest()
        {
            var t = (UdpTracker) TrackerFactory.Create(new Uri("udp://127.0.0.1:57532/announce"));
            t.RetryDelay = TimeSpan.FromMilliseconds(500);
            var id = new TrackerConnectionID(t, false, TorrentEvent.Started, new ManualResetEvent(false));

            AnnounceResponseEventArgs p = null;
            t.AnnounceComplete += delegate(object o, AnnounceResponseEventArgs e)
            {
                p = e;
                id.WaitHandle.Set();
            };
            var pars = new AnnounceParameters();
            pars.InfoHash = new InfoHash(new byte[20]);
            pars.PeerId = "";

            t.Announce(pars, id);
            Wait(id.WaitHandle);
            Assert.NotNull(p);
            Assert.False(p.Successful);
        }
예제 #33
0
        protected override async Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters)
        {
            // Clear out previous failure state
            FailureMessage = "";
            WarningMessage = "";
            var peers = new List <Peer> ();

            Uri announceString = CreateAnnounceString(parameters);
            var request        = (HttpWebRequest)WebRequest.Create(announceString);

            request.UserAgent = VersionInfo.ClientVersion;
            request.Proxy     = new WebProxy(); // If i don't do this, i can't run the webrequest. It's wierd.

            WebResponse response;

            using var cts = new CancellationTokenSource(RequestTimeout);
            using CancellationTokenRegistration registration = cts.Token.Register(() => request.Abort());

            try {
                response = await request.GetResponseAsync().ConfigureAwait(false);
            } catch (Exception ex) {
                Status         = TrackerState.Offline;
                FailureMessage = "The tracker could not be contacted";
                throw new TrackerException(FailureMessage, ex);
            }

            try {
                using CancellationTokenRegistration responseRegistration = cts.Token.Register(() => response.Close());
                using (response) {
                    peers = await AnnounceReceivedAsync(request, response).ConfigureAwait(false);

                    Status = TrackerState.Ok;
                    return(peers);
                }
            } catch (Exception ex) {
                Status         = TrackerState.InvalidResponse;
                FailureMessage = "The tracker returned an invalid or incomplete response";
                throw new TrackerException(FailureMessage, ex);
            }
        }
예제 #34
0
        public void Setup()
        {
            keys   = new List <BEncodedString> ();
            server = new MonoTorrent.Tracker.TrackerServer();
            server.AllowUnregisteredTorrents = true;
            server.RegisterListener(listener);

            peerEndpoints = new List <IPEndPoint> {
                new IPEndPoint(IPAddress.Parse("123.123.123.123"), 12312),
                new IPEndPoint(IPAddress.Parse("254.254.254.254"), 3522),
                new IPEndPoint(IPAddress.Parse("1.1.1.1"), 123),
                new IPEndPoint(IPAddress.Parse("1.2.3.4"), 65000),
            };

            tracker        = (UdpTracker)TrackerFactory.Create(new Uri($"udp://127.0.0.1:{listener.EndPoint.Port}/announce/"));
            announceparams = announceparams.WithPort(listener.EndPoint.Port);

            listener.IgnoreAnnounces    = false;
            listener.IgnoreConnects     = false;
            listener.IgnoreErrors       = false;
            listener.IgnoreScrapes      = false;
            listener.IncompleteAnnounce = listener.IncompleteConnect = listener.IncompleteScrape = false;
        }
예제 #35
0
 public ConnectAnnounceState(AnnounceParameters parameters, AsyncCallback callback, object state)
     : base(callback, state)
 {
     Parameters = parameters;
 }
예제 #36
0
 public abstract void Announce(AnnounceParameters parameters, object state);
예제 #37
0
 public abstract Task AnnounceAsync(AnnounceParameters parameters, TrackerConnectionID state);
예제 #38
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            try
            {
                Uri announceString = CreateAnnounceString(parameters);
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(announceString);
                request.UserAgent = MonoTorrent.Common.VersionInfo.ClientVersion;
                request.Proxy = new WebProxy();   // If i don't do this, i can't run the webrequest. It's wierd.
                RaiseBeforeAnnounce();
                BeginRequest(request, AnnounceReceived, new object[] { request, state });
            }
            catch (Exception ex)
            {
                Status = TrackerState.Offline;
                FailureMessage = ("Could not initiate announce request: " + ex.Message);
                RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, false));
            }

            if (state is TrackerConnectionID)
            {
                var id = ((TrackerConnectionID)state);
                if (id.WaitHandle != null)
                {
                    try
                    {
                        id.WaitHandle.Set();
                    }
                    catch
                    {

                    }
                }
            }
        }
예제 #39
0
        Uri CreateAnnounceString(AnnounceParameters parameters)
        {
            UriQueryBuilder b = new UriQueryBuilder (Uri);
            b.Add ("info_hash", parameters.InfoHash.UrlEncode ())
             .Add ("peer_id", parameters.PeerId)
             .Add ("port", parameters.Port)
             .Add ("uploaded", parameters.BytesUploaded)
             .Add ("downloaded", parameters.BytesDownloaded)
             .Add ("left", parameters.BytesLeft)
             .Add ("compact", 1)
             .Add ("numwant", 100);

            if (parameters.SupportsEncryption)
                b.Add ("supportcrypto", 1);
            if (parameters.RequireEncryption)
                b.Add ("requirecrypto", 1);
            if (!b.Contains ("key"))
                b.Add ("key", Key);
            if (!string.IsNullOrEmpty (parameters.Ipaddress))
                b.Add ("ip", parameters.Ipaddress);

            // If we have not successfully sent the started event to this tier, override the passed in started event
            // Otherwise append the event if it is not "none"
            //if (!parameters.Id.Tracker.Tier.SentStartedEvent)
            //{
            //    sb.Append("&event=started");
            //    parameters.Id.Tracker.Tier.SendingStartedEvent = true;
            //}
            if (parameters.ClientEvent != TorrentEvent.None)
                b.Add ("event", parameters.ClientEvent.ToString ().ToLower ());

            if (!string.IsNullOrEmpty (TrackerId))
                b.Add ("trackerid", TrackerId);

            return b.ToUri ();
        }
예제 #40
0
 public override void Announce(AnnounceParameters parameters, object state)
 {
     RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, true));
 }
예제 #41
0
 public override void Announce(AnnounceParameters parameters, object state)
 {
 }
예제 #42
0
        string CreateAnnounceString(AnnounceParameters parameters)
        {
            StringBuilder sb = new StringBuilder(256);

            //base.LastUpdated = DateTime.Now;
            // FIXME: This method should be tidied up. I don't like the way it current works
            sb.Append(Uri);
            sb.Append(Uri.OriginalString.Contains("?") ? '&' : '?');
            sb.Append("info_hash=");
            sb.Append(HttpUtility.UrlEncode(parameters.Infohash));
            sb.Append("&peer_id=");
            sb.Append(parameters.PeerId);
            sb.Append("&port=");
            sb.Append(parameters.Port);
            if (parameters.SupportsEncryption)
                sb.Append("&supportcrypto=1");
            if (parameters.RequireEncryption)
                sb.Append("&requirecrypto=1");
            sb.Append("&uploaded=");
            sb.Append(parameters.BytesUploaded);
            sb.Append("&downloaded=");
            sb.Append(parameters.BytesDownloaded);
            sb.Append("&left=");
            sb.Append(parameters.BytesLeft);
            sb.Append("&compact=1");    // Always use compact response
            sb.Append("&numwant=");
            sb.Append(parameters.BytesLeft == 0 ? 0 : 100);
            if (!Uri.Query.Contains("key="))
            {
                sb.Append("&key=");  // The 'key' protocol, used as a kind of 'password'. Must be the same between announces
                sb.Append(Key);
            }
            if (parameters.Ipaddress != null)
            {
                sb.Append("&ip=");
                sb.Append(parameters.Ipaddress);
            }

            // If we have not successfully sent the started event to this tier, override the passed in started event
            // Otherwise append the event if it is not "none"
            //if (!parameters.Id.Tracker.Tier.SentStartedEvent)
            //{
            //    sb.Append("&event=started");
            //    parameters.Id.Tracker.Tier.SendingStartedEvent = true;
            //}
            if (parameters.ClientEvent != TorrentEvent.None)
            {
                sb.Append("&event=");
                sb.Append(parameters.ClientEvent.ToString().ToLower());
            }

            if (!string.IsNullOrEmpty(TrackerId))
            {
                sb.Append("&trackerid=");
                sb.Append(TrackerId);
            }

            return sb.ToString();
        }
예제 #43
0
 protected abstract Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters);
예제 #44
0
        public void ScrapeTest()
        {
            Tracker.Tracker t = TrackerFactory.Create(new Uri(prefix.Substring(0, prefix.Length -1)));
            Assert.IsTrue(t.CanScrape, "#1");
            TrackerConnectionID id = new TrackerConnectionID(t, false, TorrentEvent.Started, new ManualResetEvent(false));

            AnnounceResponseEventArgs p = null;
            t.AnnounceComplete += delegate(object o, AnnounceResponseEventArgs e) {
                p = e;
                id.WaitHandle.Set();
            };
            MonoTorrent.Client.Tracker.AnnounceParameters pars = new AnnounceParameters();
            pars.Infohash = new byte[20];

            t.Announce(pars, id);
            Wait(id.WaitHandle);
            Assert.IsNotNull(p, "#2");
            Assert.IsTrue(p.Successful, "#3");
            Assert.AreEqual(1, t.Complete, "#1");
            Assert.AreEqual(0, t.Incomplete, "#2");
            Assert.AreEqual(0, t.Downloaded, "#3");
        }
예제 #45
0
 public TrackerBasedSwarm(InfoHash hash, int port, AnnounceParameters param)
     : base(hash,port)
 {
     AParams = param;
     _trackers = new List<Client.Tracker.Tracker>();
 }
예제 #46
0
        public void KeyTest()
        {
            MonoTorrent.Client.Tracker.AnnounceParameters pars = new AnnounceParameters();
            pars.Infohash = new byte[20];

            Tracker.Tracker t = TrackerFactory.Create(new Uri(prefix + "?key=value"));
            TrackerConnectionID id = new TrackerConnectionID(t, false, TorrentEvent.Started, new ManualResetEvent(false));
            t.AnnounceComplete += delegate { id.WaitHandle.Set(); };
            t.Announce(pars, id);
            Wait(id.WaitHandle);
            Assert.AreEqual("value", keys[0], "#1");
        }
예제 #47
0
 public ConnectAnnounceState(AnnounceParameters parameters, AsyncCallback callback, object state)
     : base(callback, state)
 {
     Parameters = parameters;
 }
        public void AnnounceTest()
        {
            var t = (UdpTracker) TrackerFactory.Create(new Uri(prefix));
            var id = new TrackerConnectionID(t, false, TorrentEvent.Started, new ManualResetEvent(false));

            AnnounceResponseEventArgs p = null;
            t.AnnounceComplete += delegate(object o, AnnounceResponseEventArgs e)
            {
                p = e;
                id.WaitHandle.Set();
            };
            var pars = new AnnounceParameters();
            pars.InfoHash = new InfoHash(new byte[20]);
            pars.PeerId = "";

            t.Announce(pars, id);
            Wait(id.WaitHandle);
            Assert.NotNull(p);
            Assert.True(p.Successful);
            //Assert.Equal(keys[0], t.Key);
        }
예제 #49
0
        public override void Announce(AnnounceParameters parameters, object state)
        {
            //LastUpdated = DateTime.Now;
               if (!hasConnected && amConnecting)
               {
               if (state is TrackerConnectionID)
               {
                   var id = ((TrackerConnectionID)state);
                   if (id.WaitHandle != null)
                   {
                       try
                       {
                           id.WaitHandle.Set();
                       }
                       catch
                       {

                       }
                   }
               }
               return;
               }

               if (!hasConnected)
               {
               amConnecting = true;
               try
               {
                   Connect(new ConnectAnnounceState(parameters, ConnectAnnounceCallback, state));
               }
               catch (SocketException)
               {
                   DoAnnounceComplete(false, state, new List<Peer>());
                   if (state is TrackerConnectionID)
                   {
                       var id = ((TrackerConnectionID)state);
                       if (id.WaitHandle != null)
                       {
                           try
                           {
                               id.WaitHandle.Set();
                           }
                           catch
                           {

                           }
                       }
                   }
                   return;
               }
               }
               else
               DoAnnounce(parameters, state);

               if (state is TrackerConnectionID)
               {
               var id = ((TrackerConnectionID)state);
               if (id.WaitHandle != null)
               {
                   try
                   {
                       id.WaitHandle.Set();
                   }
                   catch
                   {
                   }
               }
               }
        }
예제 #50
0
 public override void Announce(AnnounceParameters parameters, object state)
 {
     RaiseBeforeAnnounce();
     AnnouncedAt.Add(DateTime.Now);
     RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, !FailAnnounce));
 }
예제 #51
0
 protected abstract ReusableTask <AnnounceResponse> DoAnnounceAsync(AnnounceParameters parameters, CancellationToken token);
예제 #52
0
 public abstract void Announce(AnnounceParameters parameters, object state);