Package org.klomp.snark
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 Summary
Fields Modifier and Type Field Description (package private) static longCHECK_PERIODstatic longMAX_INACTIVEstatic longMAX_SEED_INACTIVE(package private) static intMAX_UPLOADERS(package private) MetaInfometainfoExternal use by PeerMonitorTask only.(package private) Deque<Peer>peerssynchronize on this when changing peers or downloaders.(package private) static intRATE_DEPTH(package private) StoragestorageExternal use by PeerMonitorTask only.
-
Constructor Summary
Constructors Constructor Description PeerCoordinator(I2PSnarkUtil util, byte[] id, byte[] infohash, MetaInfo metainfo, Storage storage, CoordinatorListener listener, Snark torrent)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddInterestedAndChoking(int toAdd)booleanaddPeer(Peer peer)Add peer (inbound or outbound)intallowedUploaders()Return number of allowed uploaders for this torrent.voidbanWebPeer(String host, boolean isPermanent)Ban a web peer for this torrent, for while or permanently.booleancompleted()voidconnected(Peer peer)Called when the connection to the peer has started and the handshake was successfull.voiddecrementUploaders(boolean isInterested)Decrement the uploaders and (if set) the interestedUploaders countsvoiddisconnected(Peer peer)Called when the connection to the peer was terminated or the connection handshake failed.voiddownloaded(Peer peer, int size)Called when a peer has downloaded some bytes of a piece.longgetCurrentUploadRate()Returns the rate in Bps over last complete CHECK_PERIOD secondslonggetDownloaded()Returns the total number of downloaded bytes of all peers.longgetDownloadRate()Returns the average rate in Bps over last RATE_DEPTH * CHECK_PERIOD secondsbyte[]getID()byte[]getInfoHash()intgetInterestedAndChoking()intgetInterestedUploaders()Uploaders, interested only.longgetLeft()Bytes not yet in storage.MetaInfogetMetaInfo()StringgetName()longgetNeededLength()Bytes still wanted.PartialPiecegetPartialPiece(Peer peer, BitField havePieces)Return partial piece to the PeerState if it's still wanted and peer has it.intgetPeerCount()might be wrongintgetPeers()should be right(package private) Set<PeerID>getPEXPeers()Called by TrackerClient(package private) static longgetRate(long[] array)StoragegetStorage()longgetUploaded()Returns the total number of uploaded bytes of all peers.intgetUploaders()Uploaders whether interested or not Use this for per-torrent limits.longgetUploadRate()Returns the average rate in Bps over last RATE_DEPTH * CHECK_PERIOD secondsI2PSnarkUtilgetUtil()ConveniencebooleangotBitField(Peer peer, BitField bitfield)Returns true if the given bitfield contains at least one piece we are interested in.voidgotChoke(Peer peer, boolean choke)this does nothing but loggingvoidgotCommentReq(Peer peer, int num)Called when comments are requested via ut_commentvoidgotComments(Peer peer, List<Comment> comments)Called when comments are received via ut_commentvoidgotExtension(Peer peer, int id, byte[] bs)PeerListener callbackbooleangotHave(Peer peer, int piece)Called when a have piece message is received.voidgotInterest(Peer peer, boolean interest)Called when an interested message is received.voidgotPeers(Peer peer, List<PeerID> peers)Get peers from PEX - PeerListener callbackbooleangotPiece(Peer peer, PartialPiece pp)Returns false if the piece is no good (according to the hash).voidgotPort(Peer peer, int port, int rport)PeerListener callback Tell the DHT to ping it, this will get back the node infoByteArraygotRequest(Peer peer, int piece, int off, int len)Returns a byte array containing the requested piece or null of the piece is unknown.voidhalt()booleanhalted()booleanisWebPeerBanned(String host)Is a web peer banned?booleanneedOutboundPeers()Outbound.booleanneedPeers()Inbound.booleanneedPiece(Peer peer, BitField havePieces)Called when we are downloading from the peer and may need to ask for a new piece.booleanoverUpBWLimit()Is snark as a whole over its limit?booleanoverUpBWLimit(long total)Is a particular peer who has downloaded this many bytes from us in the last CHECK_PERIOD over its limit?List<Peer>peerList()for web page detailed statsvoidrestart()voidsavePartialPieces(Peer peer, List<Request> partials)Save partial pieces on peer disconnection and hopefully restart it later.(package private) voidsendCommentReq(Peer peer)Send a commment request message to the peer, if he supports it.(package private) voidsendDHT(Peer peer)Send a DHT message to the peer, if we both support DHT.(package private) voidsendPeers(Peer peer)Send a PEX message to the peer, if he supports PEX.(package private) static voidsetRate(long val, long[] array)voidsetRateHistory(long up, long down)Push the total uploaded/downloaded onto a RATE_DEPTH deep stackvoidsetStorage(Storage stg)Sets the storage after transition out of magnet mode Snark calls this after we call gotMetaInfo()voidsetUploaded(long up)Sets the initial total of uploaded bytes of all peers (from a saved status)voidsetUploaders(int upl, int inter)Set the uploaders and interestedUploaders countsvoidsetWantedPieces()Only called externally from Storage after the double-check fails.(package private) voidunchokePeer()(Optimistically) unchoke.voidupdatePiecePriorities()Maps file priorities to piece priorities.voiduploaded(Peer peer, int size)Called when a peer has uploaded some bytes of a piece.intwantPiece(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.
-
-
-
Field Detail
-
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:
- Constant Field Values
-
MAX_UPLOADERS
static final int MAX_UPLOADERS
- See Also:
- Constant Field Values
-
MAX_INACTIVE
public static final long MAX_INACTIVE
- See Also:
- Constant Field Values
-
MAX_SEED_INACTIVE
public static final long MAX_SEED_INACTIVE
- See Also:
- Constant Field Values
-
RATE_DEPTH
static final int RATE_DEPTH
- See Also:
- Constant Field Values
-
-
Constructor Detail
-
PeerCoordinator
public PeerCoordinator(I2PSnarkUtil util, byte[] id, byte[] infohash, MetaInfo metainfo, Storage storage, CoordinatorListener listener, Snark torrent)
- Parameters:
metainfo- null if in magnet modestorage- null if in magnet mode
-
-
Method Detail
-
setWantedPieces
public void setWantedPieces()
Only called externally from Storage after the double-check fails. Sets wantedBytes too.
-
getStorage
public Storage getStorage()
-
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. Not exact (does not adjust for last piece size). 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:PeerListenerCalled when the connection to the peer has started and the handshake was successfull.- Specified by:
connectedin interfacePeerListener- 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:PeerListenerCalled 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:
gotHavein interfacePeerListener- 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:
gotBitFieldin interfacePeerListener- 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:
wantPiecein interfacePeerListener- 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:
gotRequestin interfacePeerListener- 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:
uploadedin interfacePeerListener- 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:
downloadedin interfacePeerListener- 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:
gotPiecein interfacePeerListener- 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:
gotChokein interfacePeerListener- 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:PeerListenerCalled when an interested message is received.- Specified by:
gotInterestin interfacePeerListener- 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:PeerListenerCalled when the connection to the peer was terminated or the connection handshake failed.- Specified by:
disconnectedin interfacePeerListener- 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:
savePartialPiecesin interfacePeerListener- 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:
getPartialPiecein interfacePeerListener- 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:
needPiecein interfacePeerListener- 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:
gotExtensionin interfacePeerListener- Parameters:
peer- the Peer that got the message.id- the message IDbs- 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:
gotPortin interfacePeerListener- Parameters:
rport- must be port + 1peer- the Peer that got the message.port- the query port- Since:
- 0.8.4
-
gotPeers
public void gotPeers(Peer peer, List<PeerID> peers)
Get peers from PEX - PeerListener callback- Specified by:
gotPeersin interfacePeerListener- 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:
gotCommentReqin interfacePeerListener- Since:
- 0.9.31
-
gotComments
public void gotComments(Peer peer, List<Comment> comments)
Called when comments are received via ut_comment- Specified by:
gotCommentsin interfacePeerListener- 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 notinter- 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:
getUtilin interfacePeerListener- 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
-
-