protected virtual void HandleHandshakeMessage(PeerId id, HandshakeMessage message) { if (!message.ProtocolString.Equals(Constants.ProtocolStringV100)) { logger.InfoFormatted(id.Connection, "Invalid protocol in handshake: {0}", message.ProtocolString); throw new ProtocolException("Invalid protocol string"); } // If we got the peer as a "compact" peer, then the peerid will be empty. In this case // we just copy the one that is in the handshake. if (BEncodedString.IsNullOrEmpty(id.Peer.PeerId)) { id.Peer.PeerId = message.PeerId; } // If the infohash doesn't match, dump the connection if (message.InfoHash != Manager.InfoHash) { logger.Info(id.Connection, "HandShake.Handle - Invalid infohash"); throw new TorrentException("Invalid infohash. Not tracking this torrent"); } // If the peer id's don't match, dump the connection. This is due to peers faking usually if (!id.Peer.PeerId.Equals(message.PeerId)) { if (Manager.HasMetadata && Manager.Torrent.IsPrivate) { // If this is a private torrent we should be careful about peerids. If they don't // match we should close the connection. I *think* uTorrent doesn't randomise peerids // for private torrents. It's not documented very well. We may need to relax this check // if other clients randomize for private torrents. logger.Info(id.Connection, "HandShake.Handle - Invalid peerid"); throw new TorrentException("Supplied PeerID didn't match the one the tracker gave us"); } else { // We don't care about the mismatch for public torrents. uTorrent randomizes its PeerId, as do other clients. id.Peer.PeerId = message.PeerId; } } // Attempt to parse the application that the peer is using id.ClientApp = new Software(message.PeerId); id.SupportsFastPeer = message.SupportsFastPeer; id.SupportsLTMessages = message.SupportsExtendedMessaging; // If they support fast peers, create their list of allowed pieces that they can request off me if (id.SupportsFastPeer && Manager != null && Manager.HasMetadata) { AllowedFastHasher ??= Manager.Engine.Factories.CreateSHA1(); id.AmAllowedFastPieces = AllowedFastAlgorithm.Calculate(AllowedFastHasher, id.AddressBytes, Manager.InfoHash, (uint)Manager.Torrent.Pieces.Count); } }
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()); }
public bool Equals(Peer other) { if (other == null) { return(false); } // FIXME: Don't compare the port, just compare the IP if (BEncodedString.IsNullOrEmpty(PeerId) || BEncodedString.IsNullOrEmpty(other.PeerId)) { return(ConnectionUri.Equals(other.ConnectionUri)); } return(PeerId.Equals(other.PeerId)); }
/// <summary> /// Creates a new tracker /// </summary> /// <param name="trackerId">The unique identifier to use as the <see cref="TrackerId"/></param> public TrackerServer(BEncodedString trackerId) { Requests = new RequestMonitor(); Torrents = new Dictionary <InfoHash, SimpleTorrentManager> (); // Generate an ID which shows that this is monotorrent, and the version, and then a unique(ish) integer. if (BEncodedString.IsNullOrEmpty(trackerId)) { lock (Random) trackerId = $"{GitInfoHelper.ClientVersion}-{Random.Next (1, int.MaxValue)}"; } TrackerId = trackerId; Listeners = new List <ITrackerListener> (); Client.ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate { Requests.Tick(); return(!Disposed); }); }
protected virtual void HandleHandshakeMessage(PeerId id, HandshakeMessage message) { if (!message.ProtocolString.Equals(VersionInfo.ProtocolStringV100)) { Logger.Log(id.Connection, "HandShake.Handle - Invalid protocol in handshake: {0}", message.ProtocolString); throw new ProtocolException("Invalid protocol string"); } // If we got the peer as a "compact" peer, then the peerid will be empty. In this case // we just copy the one that is in the handshake. if (BEncodedString.IsNullOrEmpty(id.Peer.PeerId)) { id.Peer.PeerId = message.PeerId; } // If the infohash doesn't match, dump the connection if (message.InfoHash != id.TorrentManager.InfoHash) { Logger.Log(id.Connection, "HandShake.Handle - Invalid infohash"); throw new TorrentException("Invalid infohash. Not tracking this torrent"); } // If the peer id's don't match, dump the connection. This is due to peers faking usually if (!id.Peer.PeerId.Equals(message.PeerId)) { Logger.Log(id.Connection, "HandShake.Handle - Invalid peerid"); throw new TorrentException("Supplied PeerID didn't match the one the tracker gave us"); } // Attempt to parse the application that the peer is using id.ClientApp = new Software(message.PeerId); id.SupportsFastPeer = message.SupportsFastPeer; id.SupportsLTMessages = message.SupportsExtendedMessaging; // If they support fast peers, create their list of allowed pieces that they can request off me if (id.SupportsFastPeer && id.TorrentManager != null && id.TorrentManager.HasMetadata) { id.AmAllowedFastPieces = AllowedFastAlgorithm.Calculate(id.AddressBytes, id.TorrentManager.InfoHash, (uint)id.TorrentManager.Torrent.Pieces.Count); } }
protected virtual void HandleHandshakeMessage(PeerId id, HandshakeMessage message) { if (!message.ProtocolString.Equals(Constants.ProtocolStringV100)) { logger.InfoFormatted(id.Connection, "Invalid protocol in handshake: {0}", message.ProtocolString); throw new ProtocolException("Invalid protocol string"); } // If we got the peer as a "compact" peer, then the peerid will be empty. In this case // we just copy the one that is in the handshake. if (BEncodedString.IsNullOrEmpty(id.Peer.PeerId)) { id.Peer.PeerId = message.PeerId; } // If the infohash doesn't match, dump the connection if (!Manager.InfoHashes.Contains(message.InfoHash)) { logger.Info(id.Connection, "HandShake.Handle - Invalid infohash"); throw new TorrentException("Invalid infohash. Not tracking this torrent"); } // If the peer id's don't match, dump the connection. This is due to peers faking usually if (!id.Peer.PeerId.Equals(message.PeerId)) { if (Manager.HasMetadata && Manager.Torrent !.IsPrivate) { // If this is a private torrent we should be careful about peerids. If they don't // match we should close the connection. I *think* uTorrent doesn't randomise peerids // for private torrents. It's not documented very well. We may need to relax this check // if other clients randomize for private torrents. logger.Info(id.Connection, "HandShake.Handle - Invalid peerid"); throw new TorrentException("Supplied PeerID didn't match the one the tracker gave us"); } else { // We don't care about the mismatch for public torrents. uTorrent randomizes its PeerId, as do other clients. id.Peer.PeerId = message.PeerId; } }