コード例 #1
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)
        {
            var length = peer.QueueLength;

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

                var 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));
                }
            }
        }
コード例 #2
0
ファイル: Mode.cs プロジェクト: miryuan/monotorrent
        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} byte");

            var 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));
            }
        }
コード例 #3
0
        internal void AddPieceRequests(PeerId id)
        {
            PeerMessage msg;
            var         maxRequests = id.MaxPendingRequests;

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

            var 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;
                    }
                }
            }
        }
コード例 #4
0
ファイル: Mode.cs プロジェクト: miryuan/monotorrent
        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 ());
            }
        }
コード例 #5
0
 protected virtual void HandleLtMetadataMessage(PeerId id, LTMetadata message)
 {
     if (message.MetadataMessageType == LTMetadata.eMessageType.Request)
     {
         if (Manager.HasMetadata)
         {
             id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Data, message.Piece, Manager.Torrent.Metadata));
         }
         else
         {
             id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Reject, message.Piece));
         }
     }
 }
コード例 #6
0
 public virtual void Unchoke(PeerId peerToUnchoke)
 {
     peerToUnchoke.AmChoking = false;
     peerToUnchoke.TorrentManager.UploadingTo++;
     peerToUnchoke.Enqueue(new UnchokeMessage());
     peerToUnchoke.LastUnchoked = DateTime.Now;
 }
コード例 #7
0
ファイル: Mode.cs プロジェクト: miryuan/monotorrent
        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;
                }

                var piece = msg as PieceMessage;
                if (!(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) {
                    id.Enqueue (msg);
                } else {
                    id.IsRequestingPiecesCount--;
                }
            }
        }
コード例 #8
0
        public virtual void HandlePeerConnected(PeerId id, Direction direction)
        {
            var bundle = new MessageBundle();

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

            id.Enqueue(bundle);
        }
コード例 #9
0
ファイル: MetadataMode.cs プロジェクト: miryuan/monotorrent
        void RequestNextNeededPiece(PeerId id)
        {
            int index = bitField.FirstFalse();

            if (index == -1)
            {
                return;//throw exception or switch to regular?
            }
            var m = new LTMetadata(id, LTMetadata.eMessageType.Request, index);

            id.Enqueue(m);
            requestTimeout = DateTime.Now.Add(timeout);
        }
コード例 #10
0
        protected virtual void HandleCancelMessage(PeerId id, CancelMessage message)
        {
            for (var i = 0; i < id.QueueLength; i++)
            {
                var msg = id.Dequeue();
                if (!(msg is PieceMessage))
                {
                    id.Enqueue(msg);
                    continue;
                }

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

            for (var 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;
                }
            }
        }
コード例 #11
0
        public virtual void HandlePeerConnected(PeerId id)
        {
            if (CanAcceptConnections)
            {
                var bundle = new MessageBundle();

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

                id.Enqueue(bundle);
            }
            else
            {
                ConnectionManager.CleanupSocket(Manager, id);
            }
        }
コード例 #12
0
        internal void OnTick()
        {
            if (!_id.TorrentManager.Settings.EnablePeerExchange)
            {
                return;
            }

            var len       = (_addedPeers.Count <= MaxPeers) ? _addedPeers.Count : MaxPeers;
            var added     = new byte[len * 6];
            var addedDotF = new byte[len];

            for (var i = 0; i < len; i++)
            {
                _addedPeers[i].CompactPeer(added, i * 6);
                if ((_addedPeers[i].Encryption & (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(MaxPeers - len, _droppedPeers.Count);

            var dropped = new byte[len * 6];

            for (var i = 0; i < len; i++)
            {
                _droppedPeers[i].CompactPeer(dropped, i * 6);
            }

            _droppedPeers.RemoveRange(0, len);
            _id.Enqueue(new PeerExchangeMessage(_id, added, addedDotF, dropped));
        }
コード例 #13
0
ファイル: CancelMessage.cs プロジェクト: burris/monotorrent
        /// <summary>
        /// Performs any necessary actions required to process the message
        /// </summary>
        /// <param name="id">The Peer who's message will be handled</param>
        internal override void Handle(PeerId id)
        {
            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 == this.pieceIndex && piece.StartOffset == this.startOffset && piece.RequestLength == this.requestLength))
                {
                    id.Enqueue(msg);
                }
                else
                {
                    id.IsRequestingPiecesCount--;
                }
            }
        }
コード例 #14
0
 public virtual void Choke(PeerId id)
 {
     id.AmChoking = true;
     id.TorrentManager.UploadingTo--;
     id.Enqueue(new ChokeMessage());
 }