Beispiel #1
0
        /// <summary>
        /// Updates the peer in the tracker database based on the announce parameters
        /// </summary>
        /// <param name="par"></param>
        internal void Update(AnnounceParameters par)
        {
            Peer   peer;
            object peerKey = comparer.GetKey(par);

            if (!peers.TryGetValue(peerKey, out peer))
            {
                peer = new Peer(par, peerKey);
                Add(peer);
            }
            else
            {
                Debug.WriteLine(string.Format("Updating: {0} with key {1}", peer.ClientAddress, peerKey));
                peer.Update(par);
            }
            if (par.Event == TorrentEvent.Completed)
            {
                System.Threading.Interlocked.Increment(ref downloaded.number);
            }

            else if (par.Event == TorrentEvent.Stopped)
            {
                Remove(peer);
            }

            tracker.RaisePeerAnnounced(new AnnounceEventArgs(peer, this));
            UpdateCounts();
        }
Beispiel #2
0
        public override bool Equals(object obj)
        {
            AnnounceParameters other = obj as AnnounceParameters;

            return(other == null ? false : other.clientAddress.Equals(clientAddress) &&
                   other.Port.Equals(Port));
        }
        /// <summary>
        /// Gets the peers from DHT and generates AnnounceParameters of a list of 
        /// peers and puts the peer info of this announcing peer to DHT
        /// </summary>
        /// <param name="parameters">
        /// AnnounceParameters from the requesting client. It's modified in method.
        /// </param>
        internal void HandleAnnounceRequest(AnnounceParameters parameters)
        {
            IEnumerable<PeerEntry> entries = _proxy.GetPeers(parameters.InfoHash.ToArray());
              foreach (PeerEntry entry in entries) {
            AnnounceParameters par = GenerateAnnounceParameters(
              parameters.InfoHash.ToArray(), entry);
            if (par.IsValid) {
              // Tracker will write to the par.Response but we don't use it
              // ListenerBase.Handle use par.ClientAddress to generate
              // AnnounceParameters again.
              Handle(par.Parameters, par.ClientAddress.Address, false);
            } else {
              Logger.WriteLineIf(LogLevel.Error, _log_props, string.Format(
            "Parameters invalid!"));
              continue;
            }

            //Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            //    string.Format("Tracker's response for this peer {0} from DHT: {1}",
            //    par.ClientAddress, par.Response.ToString()));
              }

              // Got all I need, now announce myself to DHT.
              try {
            _proxy.AnnouncePeer(parameters.InfoHash.ToArray(), parameters);
              } catch (Exception ex) {
            // It is OK to temporarily unable to announce to Dht. We can try the next time.
            Logger.WriteLineIf(LogLevel.Error, _log_props, string.Format(
              "Unable to reach Dht. We can try the next time.\n{0}", ex));
              }

              Logger.WriteLineIf(LogLevel.Info, _log_props,
            string.Format("DhtListener finished handling annoucement from {0}",
            parameters.RemoteAddress));
        }
Beispiel #4
0
        private void ListenerReceivedAnnounce(object sender, AnnounceParameters e)
        {
            if (disposed)
            {
                e.Response.Add(RequestParameters.FailureKey, (BEncodedString)"The tracker has been shut down");
                return;
            }

            monitor.AnnounceReceived();
            SimpleTorrentManager manager;

            // Check to see if we're monitoring the requested torrent
            lock (torrents)
            {
                if (!torrents.TryGetValue(e.InfoHash, out manager))
                {
                    if (AllowUnregisteredTorrents)
                    {
                        Add(new InfoHashTrackable(BitConverter.ToString(e.InfoHash.Hash), e.InfoHash));
                        manager = torrents[e.InfoHash];
                    }
                    else
                    {
                        e.Response.Add(RequestParameters.FailureKey, (BEncodedString)"The requested torrent is not registered with this tracker");
                        return;
                    }
                }
            }

            // If a non-compact response is expected and we do not allow non-compact responses
            // bail out
            if (!AllowNonCompact && !e.HasRequestedCompact)
            {
                e.Response.Add(RequestParameters.FailureKey, (BEncodedString)"This tracker does not support non-compact responses");
                return;
            }

            lock (manager)
            {
                // Update the tracker with the peers information. This adds the peer to the tracker,
                // updates it's information or removes it depending on the context
                manager.Update(e);

                // Clear any peers who haven't announced within the allowed timespan and may be inactive
                manager.ClearZombiePeers(DateTime.Now.Add(-TimeoutInterval));

                // Fulfill the announce request
                manager.GetPeers(e.Response, e.NumberWanted, e.HasRequestedCompact);
            }

            e.Response.Add(Tracker.IntervalKey, new BEncodedNumber((int)AnnounceInterval.TotalSeconds));
            e.Response.Add(Tracker.MinIntervalKey, new BEncodedNumber((int)MinAnnounceInterval.TotalSeconds));
            e.Response.Add(Tracker.TrackerIdKey, trackerId); // FIXME: Is this right?
            e.Response.Add(Tracker.CompleteKey, new BEncodedNumber(manager.Complete));
            e.Response.Add(Tracker.Incomplete, new BEncodedNumber(manager.Incomplete));

            //FIXME is this the right behaivour
            //if (par.TrackerId == null)
            //    par.TrackerId = "monotorrent-tracker";
        }
 /// <summary>
 /// Announces Peer to DHT with AnnounceParameters infomation.
 /// </summary>
 /// <returns>True if successful</returns>
 public void AnnouncePeer(byte[] infoHash, AnnounceParameters pars)
 {
     PeerEntry entry = new PeerEntry(pars);
       Logger.WriteLineIf(LogLevel.Verbose, _log_props,
       string.Format("Peer to be announced to DHT:\n{0}", entry.ToString()));
       AnnouncePeer(infoHash, entry);
 }
Beispiel #6
0
 /**
  * This initializes the PeerEntry to be stored in Dht
  * @param pars
  */
 public PeerEntry(AnnounceParameters pars)
 {
     /*
        * The ClientAddress here could be ["ip"] in the args of GET request
        * or, if it is null, the remote endpoint IP of the request.
        * Don't use pars.RemoteAddress
        */
       this._peer_endpoint = pars.ClientAddress;
       this._peer_id = pars.PeerId;
       this._event = pars.Event;
 }
Beispiel #7
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[] { uri.ToString() });
                var         parameters = new AnnounceParameters(0, 0, 0, TorrentEvent.Started,
                                                                infoHash, false, new string ('1', 20), "", 1411, false);
                await tier.Trackers[0].AnnounceAsync(parameters);
            }
        }
Beispiel #8
0
        internal void Update(AnnounceParameters parameters)
        {
            DateTime now         = DateTime.Now;
            double   elapsedTime = (now - lastAnnounceTime).TotalSeconds;

            if (elapsedTime < 1)
            {
                elapsedTime = 1;
            }

            clientAddress    = parameters.ClientAddress;
            downloadSpeed    = (int)((parameters.Downloaded - downloaded) / elapsedTime);
            uploadSpeed      = (int)((parameters.Uploaded - uploaded) / elapsedTime);
            downloaded       = parameters.Downloaded;
            uploaded         = parameters.Uploaded;
            left             = parameters.Left;
            peerId           = parameters.PeerId;
            lastAnnounceTime = now;
        }
        /// <summary>
        /// Updates the peer in the tracker database based on the announce parameters
        /// </summary>
        /// <param name="par"></param>
        internal void Update(AnnounceParameters par)
        {
            Peer peer;
            object peerKey = comparer.GetKey(par);
            if (!peers.TryGetValue(peerKey, out peer))
            {
                peer = new Peer(par, peerKey);
                Add(peer);
            }
            else
            {
                Debug.WriteLine(string.Format("Updating: {0} with key {1}", peer.ClientAddress, peerKey));
                peer.Update(par);
            }
            if (par.Event == TorrentEvent.Completed)
                System.Threading.Interlocked.Increment(ref downloaded.number);

            else if (par.Event == TorrentEvent.Stopped)
                Remove(peer);

            tracker.RaisePeerAnnounced(new AnnounceEventArgs(peer, this));
            UpdateCounts();
        }
 /// <summary>
 /// Generates the AnnounceParameters from PeerEntry
 /// </summary>
 private AnnounceParameters GenerateAnnounceParameters(byte[] infoHash, PeerEntry entry)
 {
     NameValueCollection c = new NameValueCollection();
       // "info_hash", "peer_id", "port", "uploaded(bytes)", "downloaded", "left", "compact"
       // InfoHash here should be just like what's in HttpRequests
       c.Add("info_hash", System.Web.HttpUtility.UrlEncode(infoHash));
       c.Add("peer_id", entry.PeerID);
       c.Add("port", entry.PeerPort.ToString());
       // Fake the mandatory fields, these are solely used to compute the upload/download speed
       c.Add("uploaded", "0");
       c.Add("downloaded", "0");
       c.Add("left", "1000");
       c.Add("compact", "1");
       // Optional but needs to set for monotorrent tracker
       if (entry.PeerState != MonoTorrent.Common.TorrentEvent.None) {
     c.Add("event", entry.PeerEventAsRequestKey);
       }
       // NOTE: "ip" is optional and we don't supply it.
       // AnnounceParameters will set entry.PeerIP as its ClientAddress.
       AnnounceParameters par = new AnnounceParameters(c, IPAddress.Parse(entry.PeerIP));
       return par;
 }
 /// <summary>
 /// Listens to event fired by HttpListener and delegates the handling 
 /// process to DhtListener where a list of peers are retrieved.
 /// </summary>
 private void OnAnnounceReceived(object sender, AnnounceParameters e)
 {
     Logger.WriteLineIf(LogLevel.Verbose, _log_props,
     string.Format("Annoucement received from {0}", e.RemoteAddress));
       try {
     _dictListener.HandleAnnounceRequest(e);
       } catch (Exception ex) {
     Logger.WriteLineIf(LogLevel.Error, _log_props,
       string.Format("Exception caught while processing announce request. {0}", ex));
     throw;
       }
 }
 public object GetKey(AnnounceParameters parameters)
 {
     return parameters.Uploaded;
 }
Beispiel #13
0
 public object GetKey(AnnounceParameters parameters)
 {
     return(parameters.Uploaded);
 }
Beispiel #14
0
 public object GetKey(AnnounceParameters parameters)
 {
     return(parameters.ClientAddress);
 }
Beispiel #15
0
 internal Peer(AnnounceParameters par, object dictionaryKey)
 {
     this.dictionaryKey = dictionaryKey;
     Update(par);
 }
Beispiel #16
0
 public object GetKey(AnnounceParameters parameters)
 {
     return parameters.ClientAddress.Address;
 }