java.lang.Object
org.klomp.snark.Peer
org.klomp.snark.WebPeer
- All Implemented Interfaces:
Comparable<Peer>, EepGet.StatusListener, BandwidthListener
BEP 19. Does not have an associated PeerState. All request tracking is done here.
Field Summary
Modifier and TypeFieldDescriptionprivate final PeerCoordinatorThe coordinator requesting the pieces.private final URIThe HTTP URL of the web seed.private static final intMost requests allowed in flight, 2 MB of pieces.private static final intFewest requests allowed in flight, 128 KB of pieces.private BitFieldThe pieces the seed has.private booleanTrue while the connection is open.private static final longTime allowed for a response header.static final byte[]The bytes identifying a BEP19 web seed, matched by the UI when it recognizes the connection.private static final longIdle time before the seed is dropped.private final booleanTrue if the torrent has several files.private longWhen the last data arrived.private RequestThe request most recently sent.private PeerListenerListener notified of the peer's messages.private final intRequests in flight we stay below.private intRequests allowed in flight at once.private final intRequests in flight we aim to keep at least.The requests from the coordinator awaiting their responses.private static final longTime a piece should be fetched within.private ThreadThe thread reading from the seed.private static final longTotal time allowed for one request.private static final byte[]BEP 47: zeros for serving padding ranges, written in blocks.Fields inherited from class Peer
_log, CHECK_PERIOD, infohash, magnetState, metainfo, RATE_DEPTH, stateModifier and TypeFieldDescriptionprotected final LogLogger for this peer instance.(package private) static final longHow often to recompute upload slots and UI download speeds.protected final byte[]SHA-1 of this torrent's info dictionary, sent in the handshake and checked against the remote copy.(package private) MagnetStateShared across all peers on this torrent.protected MetaInfoWill start out null in magnet mode.(package private) static final intNumber of samples in the upload/download rate windows.(package private) PeerState` Keeps state for in/out connections.Constructor Summary
ConstructorsConstructorDescriptionWebPeer(PeerCoordinator coord, URI uri, PeerID peerID, MetaInfo metainfo) Outgoing connection.Method Summary
Modifier and TypeMethodDescriptionprivate voidAdd requests for outstanding pieces, implementing part of PeerState.voidattemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) Attempt failed notification.voidattempting(String url) Called when a new attempt to fetch the URL is starting.voidbytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) This EepGet status listener helps maintain the state for the web page.(package private) voidcancel(int piece) Tell the other side that we are no longer interested in any of the outstanding requests (if any) for this piece.intHandle a completed message.(package private) voidDisconnects this peer, closing the socket and cleaning up state.voiddownloaded(int size) BandwidthListener interface - increments the download counter for this peer.booleanTwo Peers are equal when they have the same PeerID.private voidHandle a failed fetch, banning the webseed if appropriate.longThe inactive time.private RequestgetLowestOutstandingRequest(int piece) Returns the request with the lowest offset for the given piece.longThe max inactive time.intThe max pipeline.Returns all pieces we are currently requesting.Socket debug string, for debug printing.inthashCode()The hash code of a Peer is the hash code of the peerID.voidhave(int piece) Handle a have message.voidheaderReceived(String url, int attemptNum, String key, String val) Note: Headers are not processed, and this is not called, for most error response codes, unlessEepGet.setWriteErrorToOutput()is called before fetch().booleanisChoked()Whether we are choked.booleanWhether we are choking.booleanWhether the peer completed the torrent.booleanWhether the peer is connected.booleanWhether we are interested.booleanWhether the peer is interesting.booleanReturns whether this is a web peer.voidHandle a keep-alive message.(package private) voidrequest()Update the request queue.private booleanStarts requesting first chunk of next piece.voidRetransmit pending requests.Return partial pieces to the coordinator.voidrunConnection(I2PSnarkUtil util, PeerListener listener, BandwidthListener bwl, BitField ignore, MagnetState mState, boolean uploadOnly) Runs the connection to the other peer.voidsetChoking(boolean choke) Handle a choke or unchoke message.booleanshouldRequest(int size) Should we request this many bytes?toString()String form of the web peer.voidtransferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) Transfer complete notification.voidtransferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) Transfer failed notification.Methods inherited from class Peer
addDontHave, compareTo, disconnect, dontHave, getDestination, getDownBWLimit, getDownloaded, getDownloadRate, getHandshakeMap, getI2PSocket, getMagnetState, getPeerID, getPexLastSent, getTotalCommentsSent, getUpBWLimit, getUploaded, getUploadRate, getWhenConnected, isIncoming, isSnubbing, isUploadOnly, overDownBWLimit, overUpBWLimit, sendExtension, setHandshakeMap, setMetaInfo, setPexLastSent, setRateHistory, setTotalCommentsSent, setUploadOnly, shouldRequest, shouldSend, supportsFast, uploadedModifier and TypeMethodDescriptionvoidaddDontHave(int piece) Remember that this peer said it no longer has the piece (BEP 54 dont_have), so it is not re-requested from this peer until the remembered state expires, even if it re-announces HAVE.intCompares this peer to another byPeerID, then by internal ID.voiddisconnect(boolean deregister) Disconnects this peer if it was connected.booleandontHave(int piece) Whether this peer recently said it does not have the piece (BEP 54 dont_have).Returns the I2P destination of the connected peer.longCurrent limit in Bps.longReturns the number of bytes that have been downloaded.longReturns the average rate in Bps.Returns the extension handshake data from the peer.(package private) I2PSocketThe I2PSocket of this connection, or null if never connected.Returns the shared magnet state across all peers on this torrent.This peer's ID, assigned when it was created.longReturns the timestamp when PEX peers were last sent to this peer.(package private) intReturns the total number of UT comments sent to this peer.longCurrent limit in Bps.longReturns the number of bytes that have been uploaded.longReturns the average rate in Bps.longReturns the timestamp when the handshake completed.booleanReturns whether this is an incoming connection (initiated by the remote peer).booleanWhether or not the peer is snubbing us (unchoked but not requesting).booleanWhether the peer declared itself a partial seed (BEP 21 upload_only).booleanAre we currently over the limit?booleanIs snark as a whole over its limit?voidsendExtension(int type, byte[] payload) Sends a protocol extension message to the peer.voidsetHandshakeMap(Map<String, BEValue> map) Store the extension handshake data and update the request pipeline limit.voidsetMetaInfo(MetaInfo meta) Switches from magnet mode to normal mode with metainfo.voidsetPexLastSent(long now) Store the timestamp when PEX peers were last sent to this peer.(package private) voidPush the total uploaded/downloaded onto a RATE_DEPTH deep stack.(package private) voidsetTotalCommentsSent(int count) Store the total number of UT comments sent to this peer.voidsetUploadOnly(boolean uploadOnly) The peer declared itself a partial seed (BEP 21 upload_only).booleanshouldRequest(Peer peer, int size) Should we request this many bytes? Only true for this peer, which is how a callback that was handed one peer is prevented from answering for another.booleanshouldSend(int size) Should we send this many bytes? Do NOT callPeer.uploadedafter this.booleanReturns whether the peer supports the FAST protocol extension (BEP 6).voiduploaded(int size) Increments the upload counter for this peer.
Field Details
_coordinator
The coordinator requesting the pieces._uri
The HTTP URL of the web seed.outstandingRequests
isMultiFile
private final boolean isMultiFileTrue if the torrent has several files.lastRequest
The request most recently sent.listener
Listener notified of the peer's messages.bitfield
The pieces the seed has.thread
The thread reading from the seed.connected
private boolean connectedTrue while the connection is open.lastRcvd
private long lastRcvdWhen the last data arrived.maxRequests
private int maxRequestsRequests allowed in flight at once.IDBytes
public static final byte[] IDBytesThe bytes identifying a BEP19 web seed, matched by the UI when it recognizes the connection.HEADER_TIMEOUT
private static final long HEADER_TIMEOUTTime allowed for a response header.- See Also:
TOTAL_TIMEOUT
private static final long TOTAL_TIMEOUTTotal time allowed for one request.- See Also:
INACTIVITY_TIMEOUT
private static final long INACTIVITY_TIMEOUTIdle time before the seed is dropped.- See Also:
TARGET_FETCH_TIME
private static final long TARGET_FETCH_TIMETime a piece should be fetched within.- See Also:
ZERO_BUFFER
private static final byte[] ZERO_BUFFERBEP 47: zeros for serving padding ranges, written in blocks.ABSOLUTE_MIN_REQUESTS
private static final int ABSOLUTE_MIN_REQUESTSFewest requests allowed in flight, 128 KB of pieces.- See Also:
ABSOLUTE_MAX_REQUESTS
private static final int ABSOLUTE_MAX_REQUESTSMost requests allowed in flight, 2 MB of pieces.- See Also:
MIN_REQUESTS
private final int MIN_REQUESTSRequests in flight we aim to keep at least.MAX_REQUESTS
private final int MAX_REQUESTSRequests in flight we stay below.
Constructor Details
WebPeer
Outgoing connection. Creates a disconnected peer given a PeerID, your own id and the relevant MetaInfo.- Parameters:
coord- the coordinator that owns this web seed connectionuri- must be http with .i2p hostpeerID- the 20-byte peer id this seed publishesmetainfo- non-null
Method Details
toString
getSocket
hashCode
equals
runConnection
public void runConnection(I2PSnarkUtil util, PeerListener listener, BandwidthListener bwl, BitField ignore, MagnetState mState, boolean uploadOnly) Runs the connection to the other peer. This method does not return until the connection is terminated.- Overrides:
runConnectionin classPeer- Parameters:
util- the utility holding this client's connection settingslistener- notified when the connection is established or endsbwl- the bandwidth limiter this peer's traffic is accounted againstignore- our bitfield, ignoremState- the magnet state recording this peer's piece availabilityuploadOnly- if we are complete with skipped files, i.e. a partial seed
fail
Handle a failed fetch, banning the webseed if appropriate.- Parameters:
url- the URL that failedresp- the HTTP response code
getMaxPipeline
public int getMaxPipeline()The max pipeline.- Overrides:
getMaxPipelinein classPeer- Returns:
- maximum concurrent piece requests to this peer
isConnected
public boolean isConnected()Whether the peer is connected.- Overrides:
isConnectedin classPeer- Returns:
- true if the connection to this peer is still up
disconnect
void disconnect()Description copied from class:PeerDisconnects this peer, closing the socket and cleaning up state. Partial pieces are returned if deregister is true.- Overrides:
disconnectin classPeer
have
cancel
request
isInterested
public boolean isInterested()Whether we are interested.- Overrides:
isInterestedin classPeer- Returns:
- false always; a web seed publishes no bitfield
isInteresting
public boolean isInteresting()Whether the peer is interesting.- Overrides:
isInterestingin classPeer- Returns:
- true if we want anything more from this peer
setChoking
public void setChoking(boolean choke) Handle a choke or unchoke message.- Overrides:
setChokingin classPeer- Parameters:
choke- true to choke (stop uploading), false to unchoke (allow uploads)
isChoking
isChoked
getInactiveTime
public long getInactiveTime()The inactive time.- Overrides:
getInactiveTimein classPeer- Returns:
- ms since data was last received from this peer
getMaxInactiveTime
public long getMaxInactiveTime()The max inactive time.- Overrides:
getMaxInactiveTimein classPeer- Returns:
- inactivity limit in ms before the peer is dropped
keepAlive
retransmitRequests
public void retransmitRequests()Retransmit pending requests.- Overrides:
retransmitRequestsin classPeer
completed
isCompleted
public boolean isCompleted()Whether the peer completed the torrent.- Overrides:
isCompletedin classPeer- Returns:
- true always; a web seed is finished as soon as it connects
isWebPeer
downloaded
public void downloaded(int size) BandwidthListener interface - increments the download counter for this peer. Counted in the coordinator as well, since super doesn't have a PeerState.- Specified by:
downloadedin interfaceBandwidthListener- Overrides:
downloadedin classPeer- Parameters:
size- the number of bytes downloaded
shouldRequest
public boolean shouldRequest(int size) Should we request this many bytes?- Overrides:
shouldRequestin classPeer- Parameters:
size- the number of bytes about to be requested- Returns:
- true if the coordinator allows this peer to request that many bytes
addRequest
private void addRequest()Add requests for outstanding pieces, implementing part of PeerState.requestNextPiece
private boolean requestNextPiece()Starts requesting first chunk of next piece. Returns true if something has been added to the requests, false otherwise.- Returns:
- true if a request for the next piece, or an adopted partial piece, was queued, false if nothing was added
getRequestedPieces
returnPartialPieces
getLowestOutstandingRequest
Returns the request with the lowest offset for the given piece.- Parameters:
piece- the piece index- Returns:
- the lowest-offset request, or null
bytesTransferred
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) This EepGet status listener helps maintain the state for the web page. Total length should be == alreadyTransferred + currentWrite + bytesRemaining for all calls.- Specified by:
bytesTransferredin interfaceEepGet.StatusListener- Parameters:
alreadyTransferred- total of all attempts, not including currentWrite If nonzero on the first call, a partial file of that length was found, _and_ the server supports resume. If zero on a subsequent call after some bytes are transferred (and presumably after an attemptFailed), the server does _not_ support resume and we had to start over. To track _actual_ transfer if the output file could already exist, the listener should keep its own counter, or subtract the initial alreadyTransferred value. And watch out for alreadyTransferred resetting if a resume failed...currentWrite- since last call to the listenerbytesTransferred- includes headers, retries, redirects, discarded partial downloads, ...bytesRemaining- on this attempt only, currentWrite already subtracted - or -1 if chunked encoding or server does not return a lengthurl- the URL being fetched
attemptFailed
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) Attempt failed notification.- Specified by:
attemptFailedin interfaceEepGet.StatusListener- Parameters:
url- the address whose fetch attempt failedbytesTransferred- bytes received so far, counted across every attempt and including response headersbytesRemaining- bytes still owed, or -1 if unknowncurrentAttempt- zero-based index of the attempt that failednumRetries- total attempts this fetch is allowedcause- the exception that ended the attempt- See Also:
transferComplete
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) Transfer complete notification.- Specified by:
transferCompletein interfaceEepGet.StatusListener- Parameters:
alreadyTransferred- total bytes transferredbytesTransferred- total incl headersbytesRemaining- bytes still owed by the server, or -1 if chunked encoding or no Content-Length was returnedurl- the address the transfer was readingoutputFile- null if unknown (output stream constructor)notModified- whether 304- See Also:
transferFailed
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) Transfer failed notification.- Specified by:
transferFailedin interfaceEepGet.StatusListener- Parameters:
url- the address whose transfer failedbytesTransferred- bytes received so far, counted across every attempt and including response headersbytesRemaining- bytes still owed, or -1 if unknowncurrentAttempt- zero-based index of the attempt that failed- See Also:
headerReceived
Note: Headers are not processed, and this is not called, for most error response codes, unlessEepGet.setWriteErrorToOutput()is called before fetch(). To be changed?- Specified by:
headerReceivedin interfaceEepGet.StatusListener- Parameters:
url- the address the header arrived onattemptNum- zero-based index of the attempt the header arrived onkey- header keyval- header value
attempting
Called when a new attempt to fetch the URL is starting.- Specified by:
attemptingin interfaceEepGet.StatusListener- Parameters:
url- the URL being attempted