/// <summary>
        /// Invoked when a message is received from a connected peer.
        /// </summary>
        /// <param name="peer">Peer that sent the message.</param>
        /// <param name="data">Received message data.</param>
        public void MessageReceived(BitTorrentPeer peer, byte[] data)
        {
            if (data.Length == 0)
            {
                return;
            }

            var reader = new BigEndianBinaryReader(new MemoryStream(data));

            byte messageId = reader.ReadByte();

            _logger.LogTrace($"Message received: {messageId}");

            if (_messageHandlerRegistrations.TryGetValue(Tuple.Create(peer, messageId), out IModule module))
            {
                var customValues           = peer.GetCustomValues(module);
                var messageReceivedContext = new MessageReceivedContext(
                    peer,
                    this,
                    messageId,
                    data.Length - 1,
                    reader,
                    customValues,
                    rMessageId => RegisterModuleForMessageId(peer, module, rMessageId));

                module.OnMessageReceived(messageReceivedContext);
                _logger.LogTrace($"Message of type {messageId} handled by module {module.GetType().Name}");
            }
            else
            {
                // Unknown message type
                _logger.LogWarning($"Received unknown message type {messageId} from {peer.Address}");
                peer.Disconnect();
            }
        }
예제 #2
0
        private void BlockReceived(IMessageReceivedContext context, BitTorrentPeer peer, Block block)
        {
            peer.Requested.Remove(block.AsRequest());
            context.BlockRequests.BlockReceived(block);
            long dataOffset = context.Metainfo.PieceSize * block.PieceIndex + block.Offset;

            context.DataHandler.WriteBlockData(dataOffset, block.Data);
        }
예제 #3
0
        private void SetPeerBitfield(IMessageReceivedContext context, BitTorrentPeer peer, int pieceIndex, bool available)
        {
            peer.Available.SetPieceAvailable(pieceIndex, available);

            if (!peer.IsInterestedInRemotePeer &&
                IsBitfieldInteresting(context, peer.Available))
            {
                peer.IsInterestedInRemotePeer = true;
                peer.SendMessage(new InterestedMessage());
            }
        }
        public void PeerDisconnected(BitTorrentPeer peer)
        {
            lock (_peersLock)
            {
                _logger.LogInformation($"Disconnected from peer at {peer.Address}");
                _peers.Remove(peer);

                // TODO: optimise this
                foreach (var r in _messageHandlerRegistrations.Where(x => x.Key.Item1 == peer).ToList())
                {
                    _messageHandlerRegistrations.Remove(r.Key);
                }
            }
        }
 private void RegisterModuleForMessageId(BitTorrentPeer peer, IModule module, byte messageId)
 {
     lock (_peersLock)
         _messageHandlerRegistrations[Tuple.Create(peer, messageId)] = module;
 }
예제 #6
0
 public void PeerDisconnected(BitTorrentPeer peer)
 {
     _mainLoop.AddTask(() => _underlying.PeerDisconnected(peer));
 }
예제 #7
0
 public void MessageReceived(BitTorrentPeer peer, byte[] data)
 {
     _mainLoop.AddTask(() => _underlying.MessageReceived(peer, data));
 }
예제 #8
0
 private void SetChokedByPeer(BitTorrentPeer peer, bool choked)
 {
     peer.IsChokedByRemotePeer = choked;
 }
예제 #9
0
 private void UnchokePeer(BitTorrentPeer peer)
 {
     peer.IsChokingRemotePeer = false;
     peer.SendMessage(new UnchokeMessage());
 }
예제 #10
0
 private void SetPeerInterested(BitTorrentPeer peer, bool isInterested)
 {
     peer.IsRemotePeerInterested = isInterested;
 }
예제 #11
0
 private void SetPeerBitfield(BitTorrentPeer peer, Bitfield bitfield)
 {
     peer.Available = bitfield;
 }
예제 #12
0
 private void SetBlockRequestedByPeer(BitTorrentPeer peer, BlockRequest blockRequest)
 {
     peer.RequestedByRemotePeer.Add(blockRequest);
 }