- All Implemented Interfaces:
I2PSessionListener, I2PSessionMuxedListener, DHT
- Direct Known Subclasses:
TorrentKRPC
This class implements the DHT node communication protocol used for decentralized peer discovery in BitTorrent networks. It handles:
- Kademlia routing table management
- DHT queries (ping, find_node, get_peers, announce_peer)
- Token-based peer announcement system
- Node discovery and maintenance
- Blacklist management for unreachable nodes
I2P-Specific Modifications:
- The UDP port need not be pinged after receiving a PORT message. - The UDP (datagram) port listed in the compact node info is used to receive repliable (signed) datagrams. This is used for queries, except for announces. We call this the "query port". In addition to that UDP port, we use a second datagram port equal to the signed port + 1. This is used to receive unsigned (raw) datagrams for replies, errors, and announce queries. We call this the "response port". - Compact peer info is 32 bytes (32 byte SHA256 Hash) instead of 4 byte IP + 2 byte port. There is no peer port. - Compact node info is 54 bytes (20 byte SHA1 Hash + 32 byte SHA256 Hash + 2 byte port) instead of 20 byte SHA1 Hash + 4 byte IP + 2 byte port. Port is the query port, the response port is always the query port + 1. - The trackerless torrent dictionary "nodes" key is a list of 32 byte binary strings (SHA256 Hashes) instead of a list of lists containing a host string and a port integer.
This implementation uses I2P's datagram infrastructure for secure, anonymous DHT operations within the I2P network.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classCleaner-upper.private classFire off explorer thread.private classExplorer thread.protected classCallback for replies.Field Summary
Modifier and TypeFieldDescriptionprivate final FileBackup copy of the node file.Recently unreachable, with lastSeen() as the added-to-blacklist time.private SimpleTimer2.TimedEventQueued cleanup event, kept for cancellation.private final I2PAppContextThe app context.private final FileFile storing known DHT nodes.private SimpleTimer2.TimedEventQueued exploration event, kept for cancellation.private booleanTrue once the DHT has been joined.private final ConcurrentHashMap<NID, Token> Index to incoming opaque tokens, received in a peers or nodes reply.protected booleanTrue betweenstart()and stop(), so the reply threads know to keep going.private final DHTNodesWho we know.private final LogLogger for the DHT.private final byte[]20 byte random id.private final NID20 byte random id.private final NodeInfo20 byte random id + 32 byte Hash + 2 byte port.private longWhen the node list was last saved.private final ConcurrentHashMap<Token, NodeInfo> Index to outgoing tokens we generated, sent in reply to a get_peers query.protected intSigned datagrams.protected intUnsigned datagrams.private final AtomicLongDHT bytes received.private final AtomicLongStats.private final ConcurrentHashMap<MsgID, KRPC.ReplyWaiter> Index to sent queries awaiting reply.private booleanFalse to answer no tracker queries, keeping the instance routing-only.Infohashes this instance serves tracker queries for, empty when serving all.protected I2PSessionHook to inject and receive datagrams.private longWhen the DHT was started.private final DHTTrackerOur tracker.private final AtomicLongDHT bytes sent.private final AtomicLongDHT packets sent.private static final longInterval between blacklist cleanups.private static final intPeers held in the DHT blacklist.private static final longStagger with other cleaners.private static final longHow long since sent do we wait for a reply.private static final longTimeout for a destination lookup.static final StringFile suffix for DHT persistent storage.private static final longInterval between DHT explorations.static final NIDAll-zero NID used for pings.private static final intMax number of nodes to return.private static final intTag count below which more are sent.private static final longAge limit for inbound crypto tokens.private static final intOutbound crypto tokens held at once.private static final longHow long since generated do we delete - BEP 5 says 10 minutes.private static final intMax number of peers to return.private static final longHow often the local dht node list is saved, in milliseconds.private static final intReply code for a network failure.private static final intReply code for a node response.private static final intOverloads error codes which start with 201.private static final intReply code for a peer response.private static final intReply code for a ping response.static final booleanWhen true, generated NIDs must satisfy a cryptographic puzzle.private static final intCrypto tags sent per session.Constructor Summary
ConstructorsModifierConstructorDescriptionKRPC(I2PAppContext ctx, String baseName, I2PSession session) Create the DHT instance.protectedKRPC(I2PAppContext ctx, String baseName, I2PSession session, KRPC shared) Create the DHT instance sharing state.Method Summary
Modifier and TypeMethodDescriptionvoidServe tracker queries for the given infohash in addition to any already served.voidannounce(byte[] ih, boolean isSeed) Announce to ourselves.voidannounce(byte[] ih, byte[] peerHash, boolean isSeed) Announce somebody else we know about to ourselves.intannounce(byte[] ih, int max, long maxWait, boolean isSeed) Not recommended - usegetPeersAndAnnounce(byte[], int, long, int, long, boolean, boolean).private booleanAnnounce to a single DHT peer.voidclear()Clears the tracker and DHT data.voiddisconnected(I2PSession session) Handle a session disconnect.voiderrorOccurred(I2PSession session, String message, Throwable error) Handle a session error.private voidBootstrapping or background thread.findClosest(byte[] ih, int max) Local lookup only.getPeersAndAnnounce(byte[] ih, int max, long maxWait, int annMax, long annMaxWait, boolean isSeed, boolean noSeeds) Find peers for a torrent, announcing to the closest annMax nodes found.intgetPort()The UDP query port.intgetRPort()The UDP response port.(package private) NodeInfoheardAbout(NodeInfo nInfo) Called for bootstrap or for all nodes in a receiveNodes reply.private NodeInfoCalled for a request or response.private booleanlookupDest(NodeInfo nInfo) The dest for a NodeInfo lacking it, stored there.voidmessageAvailable(I2PSession session, int msgId, long size) For non-muxed.voidmessageAvailable(I2PSession session, int msgId, long size, int proto, int fromPort, int toPort) Instruct the client that the given session has received a message.private static byte[]Pack the given nodes' data into a single byte array for a nodes response.voidping(Destination dest, int port) Ping.private voidreceiveAnnouncePeer(MsgID msgID, InfoHash ih, byte[] tok, boolean isSeed) Handle and respond to the query.private voidreceiveError(KRPC.ReplyWaiter waiter, List<BEValue> error) Handle an error response.private voidreceiveFindNode(MsgID msgID, NodeInfo nInfo, NID tID) Handle and respond to the query.private voidreceiveGetPeers(MsgID msgID, NodeInfo nInfo, InfoHash ih, boolean noSeeds, boolean scrape) Handle and respond to the query.private voidreceiveMessage(Destination from, int fromPort, byte[] payload) Handle an incoming datagram.receiveNodes(NodeInfo nInfo, byte[] ids) Receive concatenated 54-byte NodeInfos and return as a list.receivePeers(NodeInfo nInfo, List<BEValue> peers) Receive 32-byte hashes as peer list.private voidreceivePing(MsgID msgID, NodeInfo nInfo) Handle and respond to the query.private voidreceivePong(NodeInfo nInfo, byte[] nid) If node info was previously created with the dummy NID, replace it with the received NID.private voidreceiveQuery(MsgID msgID, Destination dest, int fromPort, String method, Map<String, BEValue> args) Handle and respond to an incoming query.private voidreceiveResponse(KRPC.ReplyWaiter waiter, Map<String, BEValue> response) Handle the response and alert whoever sent the query it is responding to.removeSelf(List<NodeInfo> nodes, NodeInfo self) Remove any entries equal to ourselves from a list of candidate nodes.voidStop serving tracker queries for the given infohash.Debug info, HTML formatted.voidreportAbuse(I2PSession session, int severity) Handle a reportAbuse message from the session.private KRPC.ReplyWaitersendAnnouncePeer(NodeInfo nInfo, InfoHash ih, Token token, boolean isSeed) Send an announce_peer query to a node, on the response port.private KRPC.ReplyWaitersendFindNode(NodeInfo nInfo, NID tID) Send a find_node query to a node, on the query port.private KRPC.ReplyWaitersendGetPeers(NodeInfo nInfo, InfoHash ih, boolean noSeeds) Send a get_peers query to a node, on the query port.private booleansendMessage(Destination dest, int toPort, Map<String, Object> map, boolean repliable) Lowest-level send message call.private booleanSend a nodes response (no token).private booleanSend a nodes response (token is null for find_node, non-null for get_peers).private booleanSend a nodes response, optionally with BEP 33 scrape bloom filters.private booleanSend a peers response, optionally with BEP 33 scrape bloom filters.private KRPC.ReplyWaiterSend a ping query to a node, on the query port.private booleanSend a pong response, on the response port used by all responses.private KRPC.ReplyWaiterSend a query message.private booleanSend a response message.private booleanWhether tracker queries (get_peers and announce_peer) are served for the given infohash: all infohashes for the main instance in single-dest mode, only the configured torrents for a per-torrent instance.voidsetServeAll(boolean serveAll) Whether tracker queries are served for every infohash.intsize()Known nodes, not estimated total network size.voidstart()Start the DHT.voidstop()Stop everything.private voidCalled when a reply times out.voidunannounce(byte[] ih) Remove reference to ourselves in the local tracker.
Field Details
_context
The app context._log
Logger for the DHT._tracker
Our tracker._knownNodes
Who we know._sentQueries
Index to sent queries awaiting reply._outgoingTokens
Index to outgoing tokens we generated, sent in reply to a get_peers query._incomingTokens
Index to incoming opaque tokens, received in a peers or nodes reply._blacklist
_servedTorrents
_serveAll
private volatile boolean _serveAllFalse to answer no tracker queries, keeping the instance routing-only._cleaner
Queued cleanup event, kept for cancellation._explorer
Queued exploration event, kept for cancellation._session
Hook to inject and receive datagrams._myID
private final byte[] _myID20 byte random id._myNID
20 byte random id._myNodeInfo
20 byte random id + 32 byte Hash + 2 byte port._rPort
protected int _rPortUnsigned datagrams._qPort
protected int _qPortSigned datagrams._dhtFile
File storing known DHT nodes._backupDhtFile
Backup copy of the node file._isRunning
protected volatile boolean _isRunningTrue betweenstart()and stop(), so the reply threads know to keep going._hasBootstrapped
private volatile boolean _hasBootstrappedTrue once the DHT has been joined._rxPkts
Stats._txPkts
DHT packets sent._rxBytes
DHT bytes received._txBytes
DHT bytes sent._started
private long _startedWhen the DHT was started._nodesLastSaved
private long _nodesLastSavedWhen the node list was last saved.FAKE_NID
All-zero NID used for pings.K
private static final int KMax number of nodes to return. BEP 5 says 8.- See Also:
MAX_WANT
private static final int MAX_WANTMax number of peers to return. BEP 5 doesn't say. We'll use more than I2PSnarkUtil.MAX_CONNECTIONS since lots could be old.- See Also:
REPLY_NONE
private static final int REPLY_NONEOverloads error codes which start with 201.- See Also:
REPLY_PONG
REPLY_PEERS
REPLY_NODES
REPLY_NETWORK_FAIL
private static final int REPLY_NETWORK_FAILReply code for a network failure.- See Also:
SECURE_NID
public static final boolean SECURE_NIDWhen true, generated NIDs must satisfy a cryptographic puzzle.- See Also:
MAX_TOKEN_AGE
private static final long MAX_TOKEN_AGEHow long since generated do we delete - BEP 5 says 10 minutes.- See Also:
MAX_INBOUND_TOKEN_AGE
private static final long MAX_INBOUND_TOKEN_AGEAge limit for inbound crypto tokens.- See Also:
MAX_OUTBOUND_TOKENS
private static final int MAX_OUTBOUND_TOKENSOutbound crypto tokens held at once.- See Also:
DEFAULT_QUERY_TIMEOUT
private static final long DEFAULT_QUERY_TIMEOUTHow long since sent do we wait for a reply.- See Also:
DEST_LOOKUP_TIMEOUT
private static final long DEST_LOOKUP_TIMEOUTTimeout for a destination lookup.- See Also:
CLEAN_TIME
EXPLORE_TIME
private static final long EXPLORE_TIMEInterval between DHT explorations.- See Also:
BLACKLIST_CLEAN_TIME
private static final long BLACKLIST_CLEAN_TIMEInterval between blacklist cleanups.- See Also:
BLACKLIST_MAX_PEERS
private static final int BLACKLIST_MAX_PEERSPeers held in the DHT blacklist.- See Also:
NODES_SAVE_TIME
private static final long NODES_SAVE_TIMEHow often the local dht node list is saved, in milliseconds.- See Also:
DHT_FILE_SUFFIX
File suffix for DHT persistent storage.- See Also:
SEND_CRYPTO_TAGS
private static final int SEND_CRYPTO_TAGSCrypto tags sent per session.- See Also:
LOW_CRYPTO_TAGS
private static final int LOW_CRYPTO_TAGSTag count below which more are sent.- See Also:
Constructor Details
KRPC
Create the DHT instance.- Parameters:
ctx- the I2P context supplying the log manager and random sourcebaseName- generally "i2psnark"session- the I2P session the DHT messages are sent over
KRPC
Create the DHT instance sharing state.- Parameters:
ctx- the I2P context, supplying the log manager, random source and routerbaseName- generally "i2psnark"session- the I2P session the DHT messages are sent overshared- the KRPC instance whose routing table, tracker, and blacklist are shared with this instance, or null for a standalone instance; a TorrentKRPC passes the main instance and overrides start() andstop()to run only the message listener
Method Details
serves
Whether tracker queries (get_peers and announce_peer) are served for the given infohash: all infohashes for the main instance in single-dest mode, only the configured torrents for a per-torrent instance.- Parameters:
ih- the infohash being queried- Returns:
- true if queries for this infohash are served
setServeAll
public void setServeAll(boolean serveAll) Whether tracker queries are served for every infohash. Multi-dest mode passes false, keeping the main instance a routing-table-only node so probing the primary destination never reveals torrents hosted on per-torrent destinations.- Parameters:
serveAll- true to serve every infohash, false to serve none
addServedTorrent
Serve tracker queries for the given infohash in addition to any already served. A per-torrent DHT instance registers its own torrent; a pooled destination registers each torrent assigned to it, so probing one destination never reveals torrents hosted elsewhere.- Parameters:
ih- the infohash to serve
removeServedTorrent
Stop serving tracker queries for the given infohash. Called when a torrent is removed from a pooled destination.- Parameters:
ih- the infohash to stop serving
size
getPort
getRPort
ping
Ping. We don't have a NID yet so the node is presumed to be absent from our DHT. Non-blocking, does not wait for pong. If and when the pong is received the node will be inserted in our DHT.explore
Bootstrapping or background thread. Blocking! This is almost the same as getPeers().- Parameters:
target- the key we are searching formaxNodes- how many to contactmaxWait- how long to wait for each to reply (not total) must be > 0parallel- how many outstanding at once (unimplemented, always 1)
findClosest
getPeersAndAnnounce
public Collection<Hash> getPeersAndAnnounce(byte[] ih, int max, long maxWait, int annMax, long annMaxWait, boolean isSeed, boolean noSeeds) Find peers for a torrent, announcing to the closest annMax nodes found. This is an iterative lookup in the DHT. Blocking! Caller should run in a thread.- Specified by:
getPeersAndAnnouncein interfaceDHT- Parameters:
ih- the Info Hash (torrent)max- maximum number of peers to returnmaxWait- the maximum time to wait (ms) must be > 0annMax- the number of peers to announce toannMaxWait- the maximum total time to wait for announces, may be 0 to return immediately without waiting for acksisSeed- true if seed, false if leechnoSeeds- true if we do not want seeds in the result- Returns:
- possibly empty (never null)
announce
announce
unannounce
public void unannounce(byte[] ih) Remove reference to ourselves in the local tracker. Use when shutting down the torrent locally. Non-blocking.- Specified by:
unannouncein interfaceDHT- Parameters:
ih- the Info Hash (torrent)
announce
public int announce(byte[] ih, int max, long maxWait, boolean isSeed) Not recommended - usegetPeersAndAnnounce(byte[], int, long, int, long, boolean, boolean).Announce to the closest peers in the local DHT. This is NOT iterative - call getPeers() first to get the closest peers into the local DHT. Blocking unless maxWait <= 0 Caller should run in a thread. This also automatically announces ourself to our local tracker. For best results do a getPeersAndAnnounce() instead, as this announces to the closest in the kbuckets, it does NOT sort through the known nodes hashmap.
- Specified by:
announcein interfaceDHT- Parameters:
ih- the Info Hash (torrent)max- maximum number of peers to announce tomaxWait- the maximum total time to wait (ms) or 0 to do all in parallel and returnisSeed- true if seed, false if leech- Returns:
- the number of successful announces, not counting ourselves.
announce
Announce to a single DHT peer. Blocking unless maxWait <= 0 Caller should run in a thread. For best results do a getPeers() first so we have a token.- Parameters:
ih- the Info Hash (torrent)nInfo- the peer to announce tomaxWait- the maximum time to wait (ms) or 0 to return immediately.isSeed- true if seed, false if leech- Returns:
- true if the peer replied with a pong, or - when maxWait was 0 - true as soon as the announce was queued without waiting
start
public void start()Start the DHT. Loads the DHT from file. Can't be restarted after stopping.stop
clear
public void clear()Clears the tracker and DHT data. Call after saving DHT data to disk.renderStatusHTML
Debug info, HTML formatted.- Specified by:
renderStatusHTMLin interfaceDHT- Returns:
- HTML string with DHT status information
sendPing
Send a ping query to a node, on the query port. Blocking if we have to look up the dest for the nodeinfo.- Parameters:
nInfo- who to send it to- Returns:
- null on error
sendFindNode
Send a find_node query to a node, on the query port. Blocking if we have to look up the dest for the nodeinfo.- Parameters:
nInfo- who to send it totID- target ID we are looking for- Returns:
- null on error
sendGetPeers
Send a get_peers query to a node, on the query port. Blocking if we have to look up the dest for the nodeinfo.- Parameters:
nInfo- who to send it toih- the info hash to look upnoSeeds- true if we do not want seeds in the result- Returns:
- null on error
sendAnnouncePeer
Send an announce_peer query to a node, on the response port. Non-blocking, will fail if we don't have the dest for the nodeinfo.- Parameters:
nInfo- who to send it toih- the info hash to announcetoken- the token received from a previous get_peers responseisSeed- true if seed, false if leech- Returns:
- null on error
sendPong
sendNodes
sendNodes
Send a nodes response (token is null for find_node, non-null for get_peers).- Parameters:
nInfo- who to send it tomsgID- the message ID to respond totoken- the token to include, or null for find_node responsesids- the concatenated 54-byte node infos- Returns:
- true if the response was queued for delivery to the peer
sendNodes
private boolean sendNodes(NodeInfo nInfo, MsgID msgID, Token token, byte[] ids, byte[] bFsd, byte[] bFpe) Send a nodes response, optionally with BEP 33 scrape bloom filters.- Parameters:
nInfo- who to send it tomsgID- the message ID to respond totoken- the token to include, or null for find_node responsesids- the concatenated 54-byte node infosbFsd- 256-byte seed filter, null to omitbFpe- 256-byte peer filter, null to omit- Returns:
- true if the response was queued for delivery to the peer
sendPeers
private boolean sendPeers(NodeInfo nInfo, MsgID msgID, Token token, List<byte[]> peers, byte[] bFsd, byte[] bFpe) Send a peers response, optionally with BEP 33 scrape bloom filters.- Parameters:
nInfo- who to send it tomsgID- the message ID to respond totoken- non-null token to includepeers- the list of peer hashes to sendbFsd- 256-byte seed filter, null to omitbFpe- 256-byte peer filter, null to omit- Returns:
- true if the response was queued for delivery to the peer
sendQuery
Send a query message. Blocking if repliable and we must lookup b32.- Parameters:
nInfo- who to send it tomap- the bencoded message to sendrepliable- true for all but announce- Returns:
- null on error
sendResponse
Send a response message.- Parameters:
nInfo- who to send it tomsgID- the message ID to respond tomap- the bencoded response message- Returns:
- true if the message was queued for delivery to the peer; false if it was dropped as self-addressed or as having no destination
lookupDest
The dest for a NodeInfo lacking it, stored there. Blocking.- Parameters:
nInfo- the node to look up- Returns:
- true if a destination was resolved and cached on the node
sendMessage
private boolean sendMessage(Destination dest, int toPort, Map<String, Object> map, boolean repliable) Lowest-level send message call.- Parameters:
dest- the destination to send totoPort- the port to send tomap- the bencoded message to sendrepliable- true for all but announce- Returns:
- true if the datagram was handed to the session for delivery; false if the session is closed, the target is ourselves, or the send failed
receiveMessage
Handle an incoming datagram.- Parameters:
from- dest or null if it didn't come in on signed portfromPort- the sender's port, 1-65535 or 0 if unspecifiedpayload- the bencoded KRPC message to parse
receiveQuery
private void receiveQuery(MsgID msgID, Destination dest, int fromPort, String method, Map<String, BEValue> args) throws InvalidBEncodingExceptionHandle and respond to an incoming query. Adds sender to our DHT.- Parameters:
msgID- the message IDdest- the sender's destination, may be null for announce_peer method onlyfromPort- the sender's portmethod- the query method nameargs- the query arguments- Throws:
InvalidBEncodingException- if the message is malformed
removeSelf
Remove any entries equal to ourselves from a list of candidate nodes. Peers may echo our own node entry back to us (we include our NID in every query), and we must never query, respond to, or announce to ourselves. Near-misses (same hash with a different NID or port) are kept; they are distinct nodes and only the exact self entry is dropped here.- Parameters:
nodes- candidate nodes, not modifiedself- our own node info- Returns:
- a list without any entry equal to self, possibly empty, never null
heardFrom
heardAbout
Called for bootstrap or for all nodes in a receiveNodes reply. Package private for PersistDHT.- Parameters:
nInfo- the node heard about, whose NID timestamp is refreshed when newly added- Returns:
- non-null nodeInfo from DB if present, otherwise the nInfo parameter is returned
timeout
Called when a reply times out.- Parameters:
nInfo- the node whose reply timed out
receivePing
Handle and respond to the query.- Parameters:
msgID- the message ID of the querynInfo- the node the query came from- Throws:
InvalidBEncodingException- not thrown by this method
receiveFindNode
Handle and respond to the query.- Parameters:
msgID- the message ID of the querynInfo- the node the query came fromtID- target ID they are looking for- Throws:
InvalidBEncodingException- not thrown by this method
packNodes
receiveGetPeers
private void receiveGetPeers(MsgID msgID, NodeInfo nInfo, InfoHash ih, boolean noSeeds, boolean scrape) throws InvalidBEncodingException Handle and respond to the query.- Parameters:
msgID- the message ID of the querynInfo- the node the query came fromih- the info hash of the torrent being looked upnoSeeds- true if the requester does not want seeds in the resultscrape- true if BEP 33 scrape was requested, may add BFsd and BFpe to the response- Throws:
InvalidBEncodingException- not thrown by this method
receiveAnnouncePeer
private void receiveAnnouncePeer(MsgID msgID, InfoHash ih, byte[] tok, boolean isSeed) throws InvalidBEncodingException Handle and respond to the query. We have no node info here, it came on response port, we have to get it from the token. So we can't verify that it came from the same peer, as BEP 5 specifies.- Parameters:
msgID- the message ID of the queryih- the info hash of the torrent being announcedtok- the token from a previous get_peers response, identifies the announcerisSeed- true if the announcer claims to be a seed- Throws:
InvalidBEncodingException- not thrown by this method
receiveResponse
private void receiveResponse(KRPC.ReplyWaiter waiter, Map<String, BEValue> response) throws InvalidBEncodingExceptionHandle the response and alert whoever sent the query it is responding to. Adds sender nodeinfo to our DHT.- Parameters:
waiter- the reply waiter for the original queryresponse- the bencoded reply fields keyed by method-specific names- Throws:
InvalidBEncodingException- if the response is malformed
receiveNodes
Receive concatenated 54-byte NodeInfos and return as a list. Adds all received nodeinfos to our DHT.- Parameters:
nInfo- the peer the node list arrived from, used for logging onlyids- the concatenated node info bytes- Returns:
- list of node infos
- Throws:
InvalidBEncodingException- if the data is malformed
receivePeers
private List<Hash> receivePeers(NodeInfo nInfo, List<BEValue> peers) throws InvalidBEncodingException Receive 32-byte hashes as peer list.- Parameters:
nInfo- the peer the hash list arrived from, used for logging onlypeers- the list of peer hash values- Returns:
- list of peer hashes
- Throws:
InvalidBEncodingException- if the data is malformed
receivePong
If node info was previously created with the dummy NID, replace it with the received NID.- Parameters:
nInfo- the node the pong arrived fromnid- the node ID from the reply, replacing the dummy NID if one was in use
receiveError
private void receiveError(KRPC.ReplyWaiter waiter, List<BEValue> error) throws InvalidBEncodingException Handle an error response.- Parameters:
waiter- the reply waiter for the original queryerror- the error data (1st item is error code, 2nd is message string)- Throws:
InvalidBEncodingException- if the error data is malformed
messageAvailable
public void messageAvailable(I2PSession session, int msgId, long size, int proto, int fromPort, int toPort) Instruct the client that the given session has received a message.Will be called only if you register via addMuxedSessionListener(). Will be called only for the proto(s) and toPort(s) you register for.
- Specified by:
messageAvailablein interfaceI2PSessionMuxedListener- Parameters:
session- session to notifymsgId- message number availablesize- size of the message - why it's a long and not an int is a mysteryproto- 1-254 or 0 for unspecifiedfromPort- 1-65535 or 0 for unspecifiedtoPort- 1-65535 or 0 for unspecified
messageAvailable
For non-muxed.- Specified by:
messageAvailablein interfaceI2PSessionListener- Specified by:
messageAvailablein interfaceI2PSessionMuxedListener- Parameters:
session- session to notifymsgId- message number availablesize- size of the message payload in bytes. The I2CP payload size is an int internally and is widened to long here, so the value is never negative
reportAbuse
Handle a reportAbuse message from the session.- Specified by:
reportAbusein interfaceI2PSessionListener- Specified by:
reportAbusein interfaceI2PSessionMuxedListener- Parameters:
session- the I2P session that reported the abuse, used only for contextseverity- the abuse severity
disconnected
Handle a session disconnect.- Specified by:
disconnectedin interfaceI2PSessionListener- Specified by:
disconnectedin interfaceI2PSessionMuxedListener- Parameters:
session- the I2P session that closed
errorOccurred
Handle a session error.- Specified by:
errorOccurredin interfaceI2PSessionListener- Specified by:
errorOccurredin interfaceI2PSessionMuxedListener- Parameters:
session- the I2P session that reported the errormessage- the error messageerror- the throwable reported with the error