Example #1
0
        protected virtual void HandleCancelMessage(PeerId id, CancelMessage message)
        {
            PeerMessage msg;

            for (int i = 0; i < id.QueueLength; i++)
            {
                msg = id.Dequeue();
                if (!(msg is PieceMessage))
                {
                    id.Enqueue(msg);
                    continue;
                }

                PieceMessage piece = msg as PieceMessage;
                if (!(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength))
                {
                    id.Enqueue(msg);
                }
                else
                {
                    id.IsRequestingPiecesCount--;
                }
            }

            for (int i = 0; i < id.PieceReads.Count; i++)
            {
                if (id.PieceReads[i].PieceIndex == message.PieceIndex && id.PieceReads[i].StartOffset == message.StartOffset && id.PieceReads[i].RequestLength == message.RequestLength)
                {
                    id.IsRequestingPiecesCount--;
                    id.PieceReads.RemoveAt(i);
                    break;
                }
            }
        }
Example #2
0
        internal void AddPieceRequests(PeerId id)
        {
            int maxRequests = id.MaxPendingRequests;

            if (id.AmRequestingPiecesCount >= maxRequests)
            {
                return;
            }

            int count = 1;

            if (id.Connection is HttpConnection)
            {
                if (id.AmRequestingPiecesCount > 0)
                {
                    return;
                }

                // How many whole pieces fit into 2MB
                count = (2 * 1024 * 1024) / Manager.Torrent.PieceLength;

                // Make sure we have at least one whole piece
                count = Math.Max(count, 1);

                count *= Manager.Torrent.PieceLength / Piece.BlockSize;
            }

            if (!id.IsChoking || id.SupportsFastPeer)
            {
                while (id.AmRequestingPiecesCount < maxRequests)
                {
                    PieceRequest request = Picker.ContinueExistingRequest(id);
                    if (request != null)
                    {
                        id.Enqueue(new RequestMessage(request.PieceIndex, request.StartOffset, request.RequestLength));
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (!id.IsChoking || (id.SupportsFastPeer && id.IsAllowedFastPieces.Count > 0))
            {
                while (id.AmRequestingPiecesCount < maxRequests)
                {
                    List <PeerId>        otherPeers = Manager.Peers.ConnectedPeers ?? new List <PeerId> ();
                    IList <PieceRequest> request    = Picker.PickPiece(id, id.BitField, otherPeers, count);
                    if (request != null && request.Count > 0)
                    {
                        id.Enqueue(new RequestBundle(request));
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Example #3
0
        internal void AddPieceRequests(PeerId id)
        {
            PeerMessage msg         = null;
            int         maxRequests = id.MaxPendingRequests;

            if (id.AmRequestingPiecesCount >= maxRequests)
            {
                return;
            }

            int count = 1;

            if (id.Connection is HttpConnection)
            {
                // How many whole pieces fit into 2MB
                count = (2 * 1024 * 1024) / id.TorrentManager.Torrent.PieceLength;

                // Make sure we have at least one whole piece
                count = Math.Max(count, 1);

                count *= id.TorrentManager.Torrent.PieceLength / Piece.BlockSize;
            }

            if (!id.IsChoking || id.SupportsFastPeer)
            {
                while (id.AmRequestingPiecesCount < maxRequests)
                {
                    msg = Picker.ContinueExistingRequest(id);
                    if (msg != null)
                    {
                        id.Enqueue(msg);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (!id.IsChoking || (id.SupportsFastPeer && id.IsAllowedFastPieces.Count > 0))
            {
                while (id.AmRequestingPiecesCount < maxRequests)
                {
                    msg = Picker.PickPiece(id, id.TorrentManager.Peers.ConnectedPeers, count);
                    if (msg != null)
                    {
                        id.Enqueue(msg);
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Example #4
0
 protected virtual void HandleLtMetadataMessage(PeerId id, LTMetadata message)
 {
     if (message.MetadataMessageType == LTMetadata.eMessageType.Request)
     {
         if (id.TorrentManager.HasMetadata)
         {
             id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Data, message.Piece, id.TorrentManager.Torrent.Metadata));
         }
         else
         {
             id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Reject, message.Piece));
         }
     }
 }
Example #5
0
 public virtual void Unchoke(PeerId id)
 {
     id.AmChoking = false;
     id.TorrentManager.UploadingTo++;
     id.Enqueue(new UnchokeMessage());
     id.LastUnchoked = DateTime.Now;
 }
Example #6
0
 public virtual void Unchoke(PeerId id)
 {
     Manager.UploadingTo++;
     id.AmChoking = false;
     id.Enqueue(new UnchokeMessage());
     id.LastUnchoked.Restart();
 }
Example #7
0
 public virtual void Unchoke(PeerId id)
 {
     id.AmChoking = false;
     id.TorrentManager.UploadingTo++;
     id.Enqueue(new UnchokeMessage());
     id.LastUnchoked = DateTime.Now;
 }
Example #8
0
        protected virtual void SetAmInterestedStatus(PeerId id, bool interesting)
        {
            if (interesting && !id.AmInterested)
            {
                id.AmInterested = true;
                id.Enqueue(new InterestedMessage());

                // He's interesting, so attempt to queue up any FastPieces (if that's possible)
                manager.PieceManager.AddPieceRequests(id);
            }
            else if (!interesting && id.AmInterested)
            {
                id.AmInterested = false;
                id.Enqueue(new NotInterestedMessage());
            }
        }
Example #9
0
        public virtual void HandlePeerConnected(PeerId id, Direction direction)
        {
            MessageBundle bundle = new MessageBundle();

            AppendBitfieldMessage(id, bundle);
            AppendExtendedHandshake(id, bundle);
            AppendFastPieces(id, bundle);

            id.Enqueue(bundle);
        }
Example #10
0
        private void RequestNextNeededPiece(PeerId id)
        {
            int index = bitField.FirstFalse();
            if (index == -1)
                return;//throw exception or switch to regular?

            LTMetadata m = new LTMetadata(id, LTMetadata.eMessageType.Request, index);
            id.Enqueue(m);
            requestTimeout = DateTime.Now.Add(timeout);
        }
Example #11
0
        /// <summary>
        /// Checks the send queue of the peer to see if there are any outstanding pieces which they requested
        /// and rejects them as necessary
        /// </summary>
        /// <param name="Peer"></param>
        private void RejectPendingRequests(PeerId Peer)
        {
            PeerMessage  message;
            PieceMessage pieceMessage;
            int          length = Peer.QueueLength;

            for (int i = 0; i < length; i++)
            {
                message = Peer.Dequeue();
                if (!(message is PieceMessage))
                {
                    Peer.Enqueue(message);
                    continue;
                }

                pieceMessage = (PieceMessage)message;

                // If the peer doesn't support fast peer, then we will never requeue the message
                if (!(Peer.SupportsFastPeer && ClientEngine.SupportsFastPeer))
                {
                    Peer.IsRequestingPiecesCount--;
                    continue;
                }

                // If the peer supports fast peer, queue the message if it is an AllowedFast piece
                // Otherwise send a reject message for the piece
                if (Peer.AmAllowedFastPieces.Contains(pieceMessage.PieceIndex))
                {
                    Peer.Enqueue(pieceMessage);
                }
                else
                {
                    Peer.IsRequestingPiecesCount--;
                    Peer.Enqueue(new RejectRequestMessage(pieceMessage));
                }
            }
        }
Example #12
0
        protected virtual void HandleRequestMessage(PeerId id, RequestMessage message)
        {
            // If we are not on the last piece and the user requested a stupidly big/small amount of data
            // we will close the connection
            if (Manager.Torrent.Pieces.Count != (message.PieceIndex + 1))
            {
                if (message.RequestLength > RequestMessage.MaxSize || message.RequestLength < RequestMessage.MinSize)
                {
                    throw new MessageException("Illegal piece request received. Peer requested " + message.RequestLength.ToString() + " byte");
                }
            }

            PieceMessage m = new PieceMessage(message.PieceIndex, message.StartOffset, message.RequestLength);

            // If we're not choking the peer, enqueue the message right away
            if (!id.AmChoking)
            {
                id.IsRequestingPiecesCount++;
                id.Enqueue(m);
            }

            // If the peer supports fast peer and the requested piece is one of the allowed pieces, enqueue it
            // otherwise send back a reject request message
            else if (id.SupportsFastPeer && ClientEngine.SupportsFastPeer)
            {
                if (id.AmAllowedFastPieces.Contains(message.PieceIndex))
                {
                    id.IsRequestingPiecesCount++;
                    id.Enqueue(m);
                }
                else
                {
                    id.Enqueue(new RejectRequestMessage(m));
                }
            }
        }
Example #13
0
        public virtual void HandlePeerConnected(PeerId id)
        {
            if (CanAcceptConnections)
            {
                MessageBundle bundle = new MessageBundle();

                AppendBitfieldMessage(id, bundle);
                AppendExtendedHandshake(id, bundle);
                AppendFastPieces(id, bundle);

                id.Enqueue(bundle);
            }
            else
            {
                Manager.Engine.ConnectionManager.CleanupSocket(id);
            }
        }
        // TODO onDropped!
        #endregion


        #region Methods

        internal void OnTick()
        {
            if (!Manager.Settings.AllowPeerExchange)
            {
                return;
            }

            int len = (addedPeers.Count <= MAX_PEERS) ? addedPeers.Count : MAX_PEERS;

            byte[] added     = new byte[len * 6];
            byte[] addedDotF = new byte[len];
            for (int i = 0; i < len; i++)
            {
                addedPeers[i].CompactPeer(added, i * 6);
                if ((addedPeers[i].AllowedEncryption & (EncryptionTypes.RC4Full | EncryptionTypes.RC4Header)) != EncryptionTypes.None)
                {
                    addedDotF[i] = 0x01;
                }
                else
                {
                    addedDotF[i] = 0x00;
                }

                addedDotF[i] |= (byte)(addedPeers[i].IsSeeder ? 0x02 : 0x00);
            }
            addedPeers.RemoveRange(0, len);

            len = Math.Min(MAX_PEERS - len, droppedPeers.Count);

            byte[] dropped = new byte[len * 6];
            for (int i = 0; i < len; i++)
            {
                droppedPeers[i].CompactPeer(dropped, i * 6);
            }

            droppedPeers.RemoveRange(0, len);
            id.Enqueue(new PeerExchangeMessage(id, added, addedDotF, dropped));
        }
Example #15
0
        protected virtual void SetAmInterestedStatus(PeerId id, bool interesting)
        {
            if (interesting && !id.AmInterested)
            {
                id.AmInterested = true;
                id.Enqueue(new InterestedMessage());

                // He's interesting, so attempt to queue up any FastPieces (if that's possible)
                manager.PieceManager.AddPieceRequests(id);
            }
            else if (!interesting && id.AmInterested)
            {
                id.AmInterested = false;
                id.Enqueue(new NotInterestedMessage());
            }
        }
Example #16
0
        public virtual void HandlePeerConnected(PeerId id, Direction direction)
        {
            MessageBundle bundle = new MessageBundle();

            AppendBitfieldMessage(id, bundle);
            AppendExtendedHandshake(id, bundle);
            AppendFastPieces(id, bundle);

            id.Enqueue(bundle);
        }
Example #17
0
 public virtual void Choke(PeerId id)
 {
     id.AmChoking = true;
     id.TorrentManager.UploadingTo--;
     id.Enqueue(new ChokeMessage());
 }
Example #18
0
 protected virtual void HandleLtMetadataMessage(PeerId id, LTMetadata message)
 {
     if (message.MetadataMessageType == LTMetadata.eMessageType.Request)
     {
         if (id.TorrentManager.HasMetadata)
             id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Data, message.Piece, id.TorrentManager.Torrent.Metadata));
         else
             id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Reject, message.Piece));
     }
 }
Example #19
0
 public virtual void Choke(PeerId id)
 {
     Manager.UploadingTo--;
     id.AmChoking = true;
     id.Enqueue(new ChokeMessage());
 }
        private void RequestNextNeededPiece(PeerId id)
        {
            int index = bitField.FirstFalse();
            if (index == -1)
                return;//throw exception or switch to regular?

            LTMetadata m = new LTMetadata(id, LTMetadata.eMessageType.Request, index);
            id.Enqueue(m);
            requestTimeout = DateTime.Now.Add(timeout);
        }
Example #21
0
        /// <summary>
        /// Checks the send queue of the peer to see if there are any outstanding pieces which they requested
        /// and rejects them as necessary
        /// </summary>
        /// <param name="Peer"></param>
        private void RejectPendingRequests(PeerId Peer)
        {
            PeerMessage message;
            PieceMessage pieceMessage;
            int length = Peer.QueueLength;

            for (int i = 0; i < length; i++)
            {
                message = Peer.Dequeue();
                if (!(message is PieceMessage))
                {
                    Peer.Enqueue(message);
                    continue;
                }

                pieceMessage = (PieceMessage)message;

                // If the peer doesn't support fast peer, then we will never requeue the message
                if (!(Peer.SupportsFastPeer && ClientEngine.SupportsFastPeer))
                {
                    Peer.IsRequestingPiecesCount--;
                    continue;
                }

                // If the peer supports fast peer, queue the message if it is an AllowedFast piece
                // Otherwise send a reject message for the piece
                if (Peer.AmAllowedFastPieces.Contains(pieceMessage.PieceIndex))
                    Peer.Enqueue(pieceMessage);
                else
                {
                    Peer.IsRequestingPiecesCount--;
                    Peer.Enqueue(new RejectRequestMessage(pieceMessage));
                }
            }
        }
Example #22
0
        internal void AddPieceRequests(PeerId id)
        {
            PeerMessage msg = null;
            int maxRequests = id.MaxPendingRequests;

            if (id.AmRequestingPiecesCount >= maxRequests)
                return;

            int count = 1;
            if (id.Connection is HttpConnection)
            {
                // How many whole pieces fit into 2MB
                count = (2 * 1024 * 1024) / id.TorrentManager.Torrent.PieceLength;

                // Make sure we have at least one whole piece
                count = Math.Max(count, 1);
                
                count *= id.TorrentManager.Torrent.PieceLength / Piece.BlockSize;
            }

            if (!id.IsChoking || id.SupportsFastPeer)
            {
                while (id.AmRequestingPiecesCount < maxRequests)
                {
                    msg = Picker.ContinueExistingRequest(id);
                    if (msg != null)
                        id.Enqueue(msg);
                    else
                        break;
                } 
            }

            if (!id.IsChoking || (id.SupportsFastPeer && id.IsAllowedFastPieces.Count > 0))
            {
                while (id.AmRequestingPiecesCount < maxRequests)
                {
                    msg = Picker.PickPiece(id, id.TorrentManager.Peers.ConnectedPeers, count);
                    if (msg != null)
                        id.Enqueue(msg);
                    else
                        break;
                }
            }
        }
Example #23
0
        private void PeerBitfieldSent(PeerId id)
        {
            if (id.Connection == null)
                return;

            // Free the old buffer and get a new one to recieve the length of the next message
            //ClientEngine.BufferManager.FreeBuffer(ref id.sendBuffer);

            // Now we will enqueue a FastPiece message for each piece we will allow the peer to download
            // even if they are choked
            if (ClientEngine.SupportsFastPeer && id.SupportsFastPeer)
                for (int i = 0; i < id.AmAllowedFastPieces.Count; i++)
                    id.Enqueue(new AllowedFastMessage(id.AmAllowedFastPieces[i]));

            // Allow the auto processing of the send queue to commence
            if (id.QueueLength > 0)
                id.ConnectionManager.ProcessQueue(id);
            else
                id.ProcessingQueue = false;

            // Begin the infinite looping to receive messages
            ClientEngine.BufferManager.FreeBuffer(ref id.recieveBuffer);
            NetworkIO.ReceiveMessage(id);
        }
Example #24
0
        protected virtual void HandleCancelMessage(PeerId id, CancelMessage message)
        {
            PeerMessage msg;
            for (int i = 0; i < id.QueueLength; i++)
            {
                msg = id.Dequeue();
                if (!(msg is PieceMessage))
                {
                    id.Enqueue(msg);
                    continue;
                }

                PieceMessage piece = msg as PieceMessage;
                if (!(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength))
                {
                    id.Enqueue(msg);
                }
                else
                {
                    id.IsRequestingPiecesCount--;
                }
            }

            for (int i = 0; i < id.PieceReads.Count; i++)
            {
                if (id.PieceReads[i].PieceIndex == message.PieceIndex && id.PieceReads[i].StartOffset == message.StartOffset && id.PieceReads[i].RequestLength == message.RequestLength)
                {
                    id.IsRequestingPiecesCount--;
                    id.PieceReads.RemoveAt(i);
                    break;
                }
            }
        }
Example #25
0
        internal bool AddPieceRequest(PeerId id)
        {
            PeerMessage msg;

            // If someone can upload to us fast, queue more pieces off them. But no more than 100 blocks.
            int maxRequests = PieceManager.NormalRequestAmount + (int)(id.Monitor.DownloadSpeed / 1024.0 / BonusRequestPerKb);
            maxRequests = maxRequests > 50 ? 50 : maxRequests;

            if (id.AmRequestingPiecesCount >= maxRequests)
                return false;

            //if (this.InEndGameMode)// In endgame we only want to queue 2 pieces
            //    if (id.AmRequestingPiecesCount > PieceManager.MaxEndGameRequests)
            //        return false;

            int count = 1;
            if (id.Connection is HttpConnection)
            {
                // How many whole pieces fit into 2MB
                count = (2 * 1024 * 1024) / id.TorrentManager.Torrent.PieceLength;

                // Make sure we have at least one whole piece
                count = Math.Max(count, 1);

                count *= id.TorrentManager.Torrent.PieceLength / Piece.BlockSize;
            }

            msg = Picker.PickPiece(id, id.TorrentManager.Peers.ConnectedPeers, count);
            if (msg != null)
                id.Enqueue(msg);

            return msg != null;
        }
Example #26
0
        protected virtual void HandleRequestMessage(PeerId id, RequestMessage message)
        {
            // If we are not on the last piece and the user requested a stupidly big/small amount of data
            // we will close the connection
            if (manager.Torrent.Pieces.Count != (message.PieceIndex + 1))
                if (message.RequestLength > RequestMessage.MaxSize || message.RequestLength < RequestMessage.MinSize)
                    throw new MessageException("Illegal piece request received. Peer requested " + message.RequestLength.ToString() + " byte");

            PieceMessage m = new PieceMessage(message.PieceIndex, message.StartOffset, message.RequestLength);

            // If we're not choking the peer, enqueue the message right away
            if (!id.AmChoking)
            {
                id.IsRequestingPiecesCount++;
                id.PieceReads.Add(m);
                id.TryProcessAsyncReads();
            }

            // If the peer supports fast peer and the requested piece is one of the allowed pieces, enqueue it
            // otherwise send back a reject request message
            else if (id.SupportsFastPeer && ClientEngine.SupportsFastPeer)
            {
                if (id.AmAllowedFastPieces.Contains(message.PieceIndex))
                {
                    id.IsRequestingPiecesCount++;
                    id.PieceReads.Add(m);
                    id.TryProcessAsyncReads();
                }
                else
                    id.Enqueue(new RejectRequestMessage(m));
            }
        }