Class PeerCoordinator

java.lang.Object
org.klomp.snark.PeerCoordinator
All Implemented Interfaces:
PeerListener

class PeerCoordinator extends Object implements PeerListener
Coordinates what peer does what.
  • Field Details

    • metainfo

      MetaInfo metainfo
      External use by PeerMonitorTask only. Will be null when in magnet mode.
    • storage

      Storage storage
      External use by PeerMonitorTask only. Will be null when in magnet mode.
    • CHECK_PERIOD

      static final long CHECK_PERIOD
      See Also:
    • MAX_UPLOADERS

      static final int MAX_UPLOADERS
      See Also:
    • MAX_INACTIVE

      public static final long MAX_INACTIVE
      See Also:
    • MAX_SEED_INACTIVE

      public static final long MAX_SEED_INACTIVE
      See Also:
    • RATE_DEPTH

      static final int RATE_DEPTH
      See Also:
    • peers

      final Deque<Peer> peers
      synchronize on this when changing peers or downloaders. This is a Queue, not a Set, because PeerCheckerTask keeps things in order for choking/unchoking. External use by PeerMonitorTask only.
  • Constructor Details

    • PeerCoordinator

      public PeerCoordinator(I2PSnarkUtil util, byte[] id, byte[] infohash, MetaInfo metainfo, Storage storage, CoordinatorListener listener, Snark torrent)
      Parameters:
      metainfo - null if in magnet mode
      storage - null if in magnet mode
  • Method Details

    • setWantedPieces

      public void setWantedPieces()
      Only called externally from Storage after the double-check fails. Sets wantedBytes too.
    • getStorage

      public Storage getStorage()
    • peerList

      public List<Peer> peerList()
      for web page detailed stats
    • getID

      public byte[] getID()
    • getName

      public String getName()
    • completed

      public boolean completed()
    • getPeerCount

      public int getPeerCount()
      might be wrong
    • getPeers

      public int getPeers()
      should be right
    • getLeft

      public long getLeft()
      Bytes not yet in storage. Does NOT account for skipped files. Returns how many bytes are still needed to get the complete torrent.
      Returns:
      -1 if in magnet mode
    • getNeededLength

      public long getNeededLength()
      Bytes still wanted. DOES account for skipped files.
      Returns:
      exact value. or -1 if no storage yet.
      Since:
      0.9.1
    • getUploaded

      public long getUploaded()
      Returns the total number of uploaded bytes of all peers.
    • setUploaded

      public void setUploaded(long up)
      Sets the initial total of uploaded bytes of all peers (from a saved status)
      Since:
      0.9.15
    • getDownloaded

      public long getDownloaded()
      Returns the total number of downloaded bytes of all peers.
    • setRateHistory

      public void setRateHistory(long up, long down)
      Push the total uploaded/downloaded onto a RATE_DEPTH deep stack
    • setRate

      static void setRate(long val, long[] array)
    • getDownloadRate

      public long getDownloadRate()
      Returns the average rate in Bps over last RATE_DEPTH * CHECK_PERIOD seconds
    • getUploadRate

      public long getUploadRate()
      Returns the average rate in Bps over last RATE_DEPTH * CHECK_PERIOD seconds
    • getCurrentUploadRate

      public long getCurrentUploadRate()
      Returns the rate in Bps over last complete CHECK_PERIOD seconds
    • getRate

      static long getRate(long[] array)
    • getMetaInfo

      public MetaInfo getMetaInfo()
    • getInfoHash

      public byte[] getInfoHash()
      Since:
      0.8.4
    • needPeers

      public boolean needPeers()
      Inbound. Not halted, peers < max.
      Since:
      0.9.1
    • needOutboundPeers

      public boolean needOutboundPeers()
      Outbound. Not halted, peers < max, and need pieces.
      Since:
      0.9.1
    • halted

      public boolean halted()
    • halt

      public void halt()
    • restart

      public void restart()
      Since:
      0.9.1
    • connected

      public void connected(Peer peer)
      Description copied from interface: PeerListener
      Called when the connection to the peer has started and the handshake was successfull.
      Specified by:
      connected in interface PeerListener
      Parameters:
      peer - the Peer that just got connected.
    • addPeer

      public boolean addPeer(Peer peer)
      Add peer (inbound or outbound)
      Returns:
      true if actual attempt to add peer occurs
    • unchokePeer

      void unchokePeer()
      (Optimistically) unchoke. Must be called with peers synchronized
    • gotHave

      public boolean gotHave(Peer peer, int piece)
      Description copied from interface: PeerListener
      Called when a have piece message is received. If the method returns true and the peer has not yet received a interested message or we indicated earlier to be not interested then an interested message will be send.
      Specified by:
      gotHave in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      piece - the piece number that the per just got.
      Returns:
      true if we still want the given piece
    • gotBitField

      public boolean gotBitField(Peer peer, BitField bitfield)
      Returns true if the given bitfield contains at least one piece we are interested in.
      Specified by:
      gotBitField in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      bitfield - a BitField containing the pieces that the other side has.
      Returns:
      true when the BitField contains pieces we want, false if the piece is already known.
    • wantPiece

      public int wantPiece(Peer peer, BitField havePieces)
      Returns one of pieces in the given BitField that is still wanted or -1 if none of the given pieces are wanted.
      Specified by:
      wantPiece in interface PeerListener
      Parameters:
      peer - the Peer that will be asked to provide the piece.
      havePieces - a BitField containing the pieces that the other side has.
      Returns:
      one of the pieces from the bitfield that we want or -1 if we are no longer interested in the peer.
    • updatePiecePriorities

      public void updatePiecePriorities()
      Maps file priorities to piece priorities. Call after updating file priorities Storage.setPriority()
      Since:
      0.8.1
    • gotRequest

      public ByteArray gotRequest(Peer peer, int piece, int off, int len)
      Returns a byte array containing the requested piece or null of the piece is unknown.
      Specified by:
      gotRequest in interface PeerListener
      Parameters:
      peer - the Peer that wants the piece.
      piece - the piece number requested.
      off - byte offset into the piece.
      len - length of the chunk requested.
      Returns:
      bytes or null for errors such as not having the piece yet
      Throws:
      RuntimeException - on IOE getting the data
    • uploaded

      public void uploaded(Peer peer, int size)
      Called when a peer has uploaded some bytes of a piece.
      Specified by:
      uploaded in interface PeerListener
      Parameters:
      peer - the Peer to which size bytes where uploaded.
      size - the number of bytes that where uploaded.
    • downloaded

      public void downloaded(Peer peer, int size)
      Called when a peer has downloaded some bytes of a piece.
      Specified by:
      downloaded in interface PeerListener
      Parameters:
      peer - the Peer from which size bytes where downloaded.
      size - the number of bytes that where downloaded.
    • gotPiece

      public boolean gotPiece(Peer peer, PartialPiece pp)
      Returns false if the piece is no good (according to the hash). In that case the peer that supplied the piece should probably be blacklisted.
      Specified by:
      gotPiece in interface PeerListener
      Parameters:
      peer - the Peer that got the piece.
      pp - the piece received.
      Returns:
      true when the bytes represent the piece, false otherwise.
      Throws:
      RuntimeException - on IOE saving the piece
    • gotChoke

      public void gotChoke(Peer peer, boolean choke)
      this does nothing but logging
      Specified by:
      gotChoke in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      choke - true when the peer got a choke message, false when the peer got an unchoke message.
    • gotInterest

      public void gotInterest(Peer peer, boolean interest)
      Description copied from interface: PeerListener
      Called when an interested message is received.
      Specified by:
      gotInterest in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      interest - true when the peer got a interested message, false when the peer got an uninterested message.
    • disconnected

      public void disconnected(Peer peer)
      Description copied from interface: PeerListener
      Called when the connection to the peer was terminated or the connection handshake failed.
      Specified by:
      disconnected in interface PeerListener
      Parameters:
      peer - the Peer that just got disconnected.
    • savePartialPieces

      public void savePartialPieces(Peer peer, List<Request> partials)
      Save partial pieces on peer disconnection and hopefully restart it later. Replace a partial piece in the List if the new one is bigger. Storage method is private so we can expand to save multiple partials if we wish. Also mark the piece unrequested if this peer was the only one.
      Specified by:
      savePartialPieces in interface PeerListener
      Parameters:
      peer - partials, must include the zero-offset (empty) ones too. No dup pieces, piece.setDownloaded() must be set. len field in Requests is ignored.
      Since:
      0.8.2
    • getPartialPiece

      public PartialPiece getPartialPiece(Peer peer, BitField havePieces)
      Return partial piece to the PeerState if it's still wanted and peer has it.
      Specified by:
      getPartialPiece in interface PeerListener
      Parameters:
      havePieces - pieces the peer has, the rv will be one of these
      Returns:
      PartialPiece or null
      Since:
      0.8.2
    • needPiece

      public boolean needPiece(Peer peer, BitField havePieces)
      Called when we are downloading from the peer and may need to ask for a new piece. Returns true if wantPiece() or getPartialPiece() would return a piece.
      Specified by:
      needPiece in interface PeerListener
      Parameters:
      peer - the Peer that will be asked to provide the piece.
      havePieces - a BitField containing the pieces that the other side has.
      Returns:
      if we want any of what the peer has
      Since:
      0.8.2
    • gotExtension

      public void gotExtension(Peer peer, int id, byte[] bs)
      PeerListener callback
      Specified by:
      gotExtension in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      id - the message ID
      bs - the message payload
      Since:
      0.8.4
    • sendPeers

      void sendPeers(Peer peer)
      Send a PEX message to the peer, if he supports PEX. This just sends everybody we are connected to, we don't track new vs. old peers yet.
      Since:
      0.8.4
    • sendDHT

      void sendDHT(Peer peer)
      Send a DHT message to the peer, if we both support DHT.
      Since:
      DHT
    • sendCommentReq

      void sendCommentReq(Peer peer)
      Send a commment request message to the peer, if he supports it.
      Since:
      0.9.31
    • setStorage

      public void setStorage(Storage stg)
      Sets the storage after transition out of magnet mode Snark calls this after we call gotMetaInfo()
      Since:
      0.8.4
    • gotPort

      public void gotPort(Peer peer, int port, int rport)
      PeerListener callback Tell the DHT to ping it, this will get back the node info
      Specified by:
      gotPort in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      port - the query port
      rport - must be port + 1
      Since:
      0.8.4
    • gotPeers

      public void gotPeers(Peer peer, List<PeerID> peers)
      Get peers from PEX - PeerListener callback
      Specified by:
      gotPeers in interface PeerListener
      Parameters:
      peer - the Peer that got the message.
      peers - the peer IDs (dest hashes)
      Since:
      0.8.4
    • gotCommentReq

      public void gotCommentReq(Peer peer, int num)
      Called when comments are requested via ut_comment
      Specified by:
      gotCommentReq in interface PeerListener
      Since:
      0.9.31
    • gotComments

      public void gotComments(Peer peer, List<Comment> comments)
      Called when comments are received via ut_comment
      Specified by:
      gotComments in interface PeerListener
      Parameters:
      comments - non-null
      Since:
      0.9.31
    • getPEXPeers

      Set<PeerID> getPEXPeers()
      Called by TrackerClient
      Returns:
      the Set itself, modifiable, not a copy, caller should clear()
      Since:
      0.8.4
    • allowedUploaders

      public int allowedUploaders()
      Return number of allowed uploaders for this torrent. Check with Snark to see if we are over the total upload limit.
    • getUploaders

      public int getUploaders()
      Uploaders whether interested or not Use this for per-torrent limits.
      Returns:
      current
      Since:
      0.8.4
    • getInterestedUploaders

      public int getInterestedUploaders()
      Uploaders, interested only. Use this to calculate the global total, so that unchoked but uninterested peers don't count against the global limit.
      Returns:
      current
      Since:
      0.9.28
    • setUploaders

      public void setUploaders(int upl, int inter)
      Set the uploaders and interestedUploaders counts
      Parameters:
      upl - whether interested or not
      inter - interested only
      Since:
      0.9.28
    • decrementUploaders

      public void decrementUploaders(boolean isInterested)
      Decrement the uploaders and (if set) the interestedUploaders counts
      Since:
      0.9.28
    • getInterestedAndChoking

      public int getInterestedAndChoking()
      Returns:
      current
      Since:
      0.9.28
    • addInterestedAndChoking

      public void addInterestedAndChoking(int toAdd)
      Since:
      0.9.28
    • overUpBWLimit

      public boolean overUpBWLimit()
      Is snark as a whole over its limit?
    • overUpBWLimit

      public boolean overUpBWLimit(long total)
      Is a particular peer who has downloaded this many bytes from us in the last CHECK_PERIOD over its limit?
    • getUtil

      public I2PSnarkUtil getUtil()
      Convenience
      Specified by:
      getUtil in interface PeerListener
      Since:
      0.9.2
    • banWebPeer

      public void banWebPeer(String host, boolean isPermanent)
      Ban a web peer for this torrent, for while or permanently.
      Parameters:
      host - the hostname
      Since:
      0.9.49
    • isWebPeerBanned

      public boolean isWebPeerBanned(String host)
      Is a web peer banned?
      Parameters:
      host - the hostname
      Since:
      0.9.49