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); } }
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"); }
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); }
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 { } } } }
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); }
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])); }
public async Task <List <Peer> > AnnounceAsync(AnnounceParameters parameters) { var result = await DoAnnounceAsync(parameters); LastAnnounced.Restart(); return(result); }
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); } }
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); } }
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); } }
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)); }
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"); }
public async ReusableTask <AnnounceResponse> AnnounceAsync(AnnounceParameters parameters, CancellationToken token) { try { return(await DoAnnounceAsync(parameters, token)); } finally { LastAnnounced.Restart(); } }
public async void Announce(AnnounceParameters parameters, TrackerConnectionID state) { try { await AnnounceAsync(parameters, state); } catch { // Ignore } }
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>()); } }
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); } }
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>()); } }
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 { } }
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()); }
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); } }
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); } }
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); } }
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; }
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; }
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"); }
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); } }
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); } }
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; } }
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); }
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); }
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); } }
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; }
public ConnectAnnounceState(AnnounceParameters parameters, AsyncCallback callback, object state) : base(callback, state) { Parameters = parameters; }
public abstract void Announce(AnnounceParameters parameters, object state);
public abstract Task AnnounceAsync(AnnounceParameters parameters, TrackerConnectionID state);
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 (); }
public override void Announce(AnnounceParameters parameters, object state) { RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, true)); }
public override void Announce(AnnounceParameters parameters, object state) { }
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(); }
protected abstract Task <List <Peer> > DoAnnounceAsync(AnnounceParameters parameters);
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"); }
public TrackerBasedSwarm(InfoHash hash, int port, AnnounceParameters param) : base(hash,port) { AParams = param; _trackers = new List<Client.Tracker.Tracker>(); }
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"); }
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); }
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 { } } } }
public override void Announce(AnnounceParameters parameters, object state) { RaiseBeforeAnnounce(); AnnouncedAt.Add(DateTime.Now); RaiseAnnounceComplete(new AnnounceResponseEventArgs(this, state, !FailAnnounce)); }
protected abstract ReusableTask <AnnounceResponse> DoAnnounceAsync(AnnounceParameters parameters, CancellationToken token);