java.lang.Object
org.klomp.snark.dht.KRPC
All Implemented Interfaces:
I2PSessionListener, I2PSessionMuxedListener, DHT
Direct Known Subclasses:
TorrentKRPC

public class KRPCextends Object implements I2PSessionMuxedListener, DHT
Kademlia Remote Procedure Call implementation for BitTorrent DHT (BEP 5) adapted for I2P.

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.

  • Field Details

    • _context

      private final I2PAppContext _context
      The app context.
    • _log

      private final Log _log
      Logger for the DHT.
    • _tracker

      private final DHTTracker _tracker
      Our tracker.
    • _knownNodes

      private final DHTNodes _knownNodes
      Who we know.
    • _sentQueries

      private final ConcurrentHashMap<MsgID, KRPC.ReplyWaiter> _sentQueries
      Index to sent queries awaiting reply.
    • _outgoingTokens

      private final ConcurrentHashMap<Token,NodeInfo> _outgoingTokens
      Index to outgoing tokens we generated, sent in reply to a get_peers query.
    • _incomingTokens

      private final ConcurrentHashMap<NID,Token> _incomingTokens
      Index to incoming opaque tokens, received in a peers or nodes reply.
    • _blacklist

      private final Set<NID> _blacklist
      Recently unreachable, with lastSeen() as the added-to-blacklist time.
    • _servedTorrents

      private final Set<InfoHash> _servedTorrents
      Infohashes this instance serves tracker queries for, empty when serving all.
    • _serveAll

      private volatile boolean _serveAll
      False to answer no tracker queries, keeping the instance routing-only.
    • _cleaner

      private SimpleTimer2.TimedEvent _cleaner
      Queued cleanup event, kept for cancellation.
    • _explorer

      private SimpleTimer2.TimedEvent _explorer
      Queued exploration event, kept for cancellation.
    • _session

      protected I2PSession _session
      Hook to inject and receive datagrams.
    • _myID

      private final byte[] _myID
      20 byte random id.
    • _myNID

      private final NID _myNID
      20 byte random id.
    • _myNodeInfo

      private final NodeInfo _myNodeInfo
      20 byte random id + 32 byte Hash + 2 byte port.
    • _rPort

      protected int _rPort
      Unsigned datagrams.
    • _qPort

      protected int _qPort
      Signed datagrams.
    • _dhtFile

      private final File _dhtFile
      File storing known DHT nodes.
    • _backupDhtFile

      private final File _backupDhtFile
      Backup copy of the node file.
    • _isRunning

      protected volatile boolean _isRunning
      True between start() and stop(), so the reply threads know to keep going.
    • _hasBootstrapped

      private volatile boolean _hasBootstrapped
      True once the DHT has been joined.
    • _rxPkts

      private final AtomicLong _rxPkts
      Stats.
    • _txPkts

      private final AtomicLong _txPkts
      DHT packets sent.
    • _rxBytes

      private final AtomicLong _rxBytes
      DHT bytes received.
    • _txBytes

      private final AtomicLong _txBytes
      DHT bytes sent.
    • _started

      private long _started
      When the DHT was started.
    • _nodesLastSaved

      private long _nodesLastSaved
      When the node list was last saved.
    • FAKE_NID

      public static final NID FAKE_NID
      All-zero NID used for pings.
    • K

      private static final int K
      Max number of nodes to return. BEP 5 says 8.
      See Also:
    • MAX_WANT

      private static final int MAX_WANT
      Max 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_NONE
      Overloads error codes which start with 201.
      See Also:
    • REPLY_PONG

      private static final int REPLY_PONG
      Reply code for a ping response.
      See Also:
    • REPLY_PEERS

      private static final int REPLY_PEERS
      Reply code for a peer response.
      See Also:
    • REPLY_NODES

      private static final int REPLY_NODES
      Reply code for a node response.
      See Also:
    • REPLY_NETWORK_FAIL

      private static final int REPLY_NETWORK_FAIL
      Reply code for a network failure.
      See Also:
    • SECURE_NID

      public static final boolean SECURE_NID
      When true, generated NIDs must satisfy a cryptographic puzzle.
      See Also:
    • MAX_TOKEN_AGE

      private static final long MAX_TOKEN_AGE
      How long since generated do we delete - BEP 5 says 10 minutes.
      See Also:
    • MAX_INBOUND_TOKEN_AGE

      private static final long MAX_INBOUND_TOKEN_AGE
      Age limit for inbound crypto tokens.
      See Also:
    • MAX_OUTBOUND_TOKENS

      private static final int MAX_OUTBOUND_TOKENS
      Outbound crypto tokens held at once.
      See Also:
    • DEFAULT_QUERY_TIMEOUT

      private static final long DEFAULT_QUERY_TIMEOUT
      How long since sent do we wait for a reply.
      See Also:
    • DEST_LOOKUP_TIMEOUT

      private static final long DEST_LOOKUP_TIMEOUT
      Timeout for a destination lookup.
      See Also:
    • CLEAN_TIME

      private static final long CLEAN_TIME
      Stagger with other cleaners.
      See Also:
    • EXPLORE_TIME

      private static final long EXPLORE_TIME
      Interval between DHT explorations.
      See Also:
    • BLACKLIST_CLEAN_TIME

      private static final long BLACKLIST_CLEAN_TIME
      Interval between blacklist cleanups.
      See Also:
    • BLACKLIST_MAX_PEERS

      private static final int BLACKLIST_MAX_PEERS
      Peers held in the DHT blacklist.
      See Also:
    • NODES_SAVE_TIME

      private static final long NODES_SAVE_TIME
      How often the local dht node list is saved, in milliseconds.
      See Also:
    • DHT_FILE_SUFFIX

      public static final String DHT_FILE_SUFFIX
      File suffix for DHT persistent storage.
      See Also:
    • SEND_CRYPTO_TAGS

      private static final int SEND_CRYPTO_TAGS
      Crypto tags sent per session.
      See Also:
    • LOW_CRYPTO_TAGS

      private static final int LOW_CRYPTO_TAGS
      Tag count below which more are sent.
      See Also:
  • Constructor Details

    • KRPC

      public KRPC(I2PAppContext ctx, String baseName, I2PSession session)
      Create the DHT instance.
      Parameters:
      ctx - the I2P context supplying the log manager and random source
      baseName - generally "i2psnark"
      session - the I2P session the DHT messages are sent over
    • KRPC

      protected KRPC(I2PAppContext ctx, String baseName, I2PSession session, KRPC shared)
      Create the DHT instance sharing state.
      Parameters:
      ctx - the I2P context, supplying the log manager, random source and router
      baseName - generally "i2psnark"
      session - the I2P session the DHT messages are sent over
      shared - 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() and stop() to run only the message listener
  • Method Details

    • serves

      private boolean serves(InfoHash ih)
      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

      public void addServedTorrent(InfoHash ih)
      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

      public void removeServedTorrent(InfoHash ih)
      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

      public int size()
      Known nodes, not estimated total network size.
      Specified by:
      size in interface DHT
      Returns:
      the number of known nodes
    • getPort

      public int getPort()
      The UDP query port.
      Specified by:
      getPort in interface DHT
      Returns:
      the port number
    • getRPort

      public int getRPort()
      The UDP response port.
      Specified by:
      getRPort in interface DHT
      Returns:
      the port number
    • ping

      public void ping(Destination dest, int port)
      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.
      Specified by:
      ping in interface DHT
      Parameters:
      dest - the destination to ping
      port - the UDP port to ping
    • explore

      private void explore(NID target, int maxNodes, long maxWait, int parallel)
      Bootstrapping or background thread. Blocking! This is almost the same as getPeers().
      Parameters:
      target - the key we are searching for
      maxNodes - how many to contact
      maxWait - how long to wait for each to reply (not total) must be > 0
      parallel - how many outstanding at once (unimplemented, always 1)
    • findClosest

      public List<NodeInfo> findClosest(byte[] ih, int max)
      Local lookup only.
      Parameters:
      ih - a 20-byte info hash
      max - max to return
      Returns:
      list or empty list (never null)
    • 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:
      getPeersAndAnnounce in interface DHT
      Parameters:
      ih - the Info Hash (torrent)
      max - maximum number of peers to return
      maxWait - the maximum time to wait (ms) must be > 0
      annMax - the number of peers to announce to
      annMaxWait - the maximum total time to wait for announces, may be 0 to return immediately without waiting for acks
      isSeed - true if seed, false if leech
      noSeeds - true if we do not want seeds in the result
      Returns:
      possibly empty (never null)
    • announce

      public void announce(byte[] ih, boolean isSeed)
      Announce to ourselves. Non-blocking.
      Specified by:
      announce in interface DHT
      Parameters:
      ih - the Info Hash (torrent)
      isSeed - true if seed, false if leech
    • announce

      public void announce(byte[] ih, byte[] peerHash, boolean isSeed)
      Announce somebody else we know about to ourselves. Non-blocking.
      Specified by:
      announce in interface DHT
      Parameters:
      ih - the Info Hash (torrent)
      peerHash - the peer's Hash
      isSeed - true if seed, false if leech
    • 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:
      unannounce in interface DHT
      Parameters:
      ih - the Info Hash (torrent)
    • announce

      public int announce(byte[] ih, int max, long maxWait, boolean isSeed)
      Not recommended - use getPeersAndAnnounce(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:
      announce in interface DHT
      Parameters:
      ih - the Info Hash (torrent)
      max - maximum number of peers to announce to
      maxWait - the maximum total time to wait (ms) or 0 to do all in parallel and return
      isSeed - true if seed, false if leech
      Returns:
      the number of successful announces, not counting ourselves.
    • announce

      private boolean announce(byte[] ih, NodeInfo nInfo, long maxWait, boolean isSeed)
      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 to
      maxWait - 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

      public void stop()
      Stop everything.
      Specified by:
      stop in interface DHT
    • clear

      public void clear()
      Clears the tracker and DHT data. Call after saving DHT data to disk.
    • renderStatusHTML

      public String renderStatusHTML()
      Debug info, HTML formatted.
      Specified by:
      renderStatusHTML in interface DHT
      Returns:
      HTML string with DHT status information
    • sendPing

      private KRPC.ReplyWaiter sendPing(NodeInfo nInfo)
      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

      private KRPC.ReplyWaiter sendFindNode(NodeInfo nInfo, NID tID)
      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 to
      tID - target ID we are looking for
      Returns:
      null on error
    • sendGetPeers

      private KRPC.ReplyWaiter sendGetPeers(NodeInfo nInfo, InfoHash ih, boolean noSeeds)
      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 to
      ih - the info hash to look up
      noSeeds - true if we do not want seeds in the result
      Returns:
      null on error
    • sendAnnouncePeer

      private KRPC.ReplyWaiter sendAnnouncePeer(NodeInfo nInfo, InfoHash ih, Token token, boolean isSeed)
      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 to
      ih - the info hash to announce
      token - the token received from a previous get_peers response
      isSeed - true if seed, false if leech
      Returns:
      null on error
    • sendPong

      private boolean sendPong(NodeInfo nInfo, MsgID msgID)
      Send a pong response, on the response port used by all responses.
      Parameters:
      nInfo - who to send it to
      msgID - the message ID to respond to
      Returns:
      true if the response was queued for delivery to the peer
    • sendNodes

      private boolean sendNodes(NodeInfo nInfo, MsgID msgID, byte[] ids)
      Send a nodes response (no token).
      Parameters:
      nInfo - who to send it to
      msgID - the message ID to respond to
      ids - 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)
      Send a nodes response (token is null for find_node, non-null for get_peers).
      Parameters:
      nInfo - who to send it to
      msgID - the message ID to respond to
      token - the token to include, or null for find_node responses
      ids - 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 to
      msgID - the message ID to respond to
      token - the token to include, or null for find_node responses
      ids - the concatenated 54-byte node infos
      bFsd - 256-byte seed filter, null to omit
      bFpe - 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 to
      msgID - the message ID to respond to
      token - non-null token to include
      peers - the list of peer hashes to send
      bFsd - 256-byte seed filter, null to omit
      bFpe - 256-byte peer filter, null to omit
      Returns:
      true if the response was queued for delivery to the peer
    • sendQuery

      private KRPC.ReplyWaiter sendQuery(NodeInfo nInfo, Map<String,Object> map, boolean repliable)
      Send a query message. Blocking if repliable and we must lookup b32.
      Parameters:
      nInfo - who to send it to
      map - the bencoded message to send
      repliable - true for all but announce
      Returns:
      null on error
    • sendResponse

      private boolean sendResponse(NodeInfo nInfo, MsgID msgID, Map<String,Object> map)
      Send a response message.
      Parameters:
      nInfo - who to send it to
      msgID - the message ID to respond to
      map - 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

      private boolean lookupDest(NodeInfo nInfo)
      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 to
      toPort - the port to send to
      map - the bencoded message to send
      repliable - 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

      private void receiveMessage(Destination from, int fromPort, byte[] payload)
      Handle an incoming datagram.
      Parameters:
      from - dest or null if it didn't come in on signed port
      fromPort - the sender's port, 1-65535 or 0 if unspecified
      payload - the bencoded KRPC message to parse
    • receiveQuery

      private void receiveQuery(MsgID msgID, Destination dest, int fromPort, String method, Map<String,BEValue> args) throws InvalidBEncodingException
      Handle and respond to an incoming query. Adds sender to our DHT.
      Parameters:
      msgID - the message ID
      dest - the sender's destination, may be null for announce_peer method only
      fromPort - the sender's port
      method - the query method name
      args - the query arguments
      Throws:
      InvalidBEncodingException - if the message is malformed
    • removeSelf

      static List<NodeInfo> removeSelf(List<NodeInfo> nodes, NodeInfo self)
      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 modified
      self - our own node info
      Returns:
      a list without any entry equal to self, possibly empty, never null
    • heardFrom

      private NodeInfo heardFrom(NodeInfo nInfo)
      Called for a request or response.
      Parameters:
      nInfo - the node we heard from
      Returns:
      old NodeInfo or nInfo if none, use this to reduce object churn
    • heardAbout

      NodeInfo heardAbout(NodeInfo nInfo)
      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

      private void timeout(NodeInfo nInfo)
      Called when a reply times out.
      Parameters:
      nInfo - the node whose reply timed out
    • receivePing

      private void receivePing(MsgID msgID, NodeInfo nInfo) throws InvalidBEncodingException
      Handle and respond to the query.
      Parameters:
      msgID - the message ID of the query
      nInfo - the node the query came from
      Throws:
      InvalidBEncodingException - not thrown by this method
    • receiveFindNode

      private void receiveFindNode(MsgID msgID, NodeInfo nInfo, NID tID) throws InvalidBEncodingException
      Handle and respond to the query.
      Parameters:
      msgID - the message ID of the query
      nInfo - the node the query came from
      tID - target ID they are looking for
      Throws:
      InvalidBEncodingException - not thrown by this method
    • packNodes

      private static byte[] packNodes(List<NodeInfo> nodes)
      Pack the given nodes' data into a single byte array for a nodes response.
      Parameters:
      nodes - the nodes to pack
      Returns:
      the packed node data
    • 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 query
      nInfo - the node the query came from
      ih - the info hash of the torrent being looked up
      noSeeds - true if the requester does not want seeds in the result
      scrape - 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 query
      ih - the info hash of the torrent being announced
      tok - the token from a previous get_peers response, identifies the announcer
      isSeed - 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 InvalidBEncodingException
      Handle 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 query
      response - the bencoded reply fields keyed by method-specific names
      Throws:
      InvalidBEncodingException - if the response is malformed
    • receiveNodes

      private List<NodeInfo> receiveNodes(NodeInfo nInfo, byte[] ids) throws InvalidBEncodingException
      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 only
      ids - 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 only
      peers - the list of peer hash values
      Returns:
      list of peer hashes
      Throws:
      InvalidBEncodingException - if the data is malformed
    • receivePong

      private void receivePong(NodeInfo nInfo, byte[] nid)
      If node info was previously created with the dummy NID, replace it with the received NID.
      Parameters:
      nInfo - the node the pong arrived from
      nid - 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 query
      error - 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:
      messageAvailable in interface I2PSessionMuxedListener
      Parameters:
      session - session to notify
      msgId - message number available
      size - size of the message - why it's a long and not an int is a mystery
      proto - 1-254 or 0 for unspecified
      fromPort - 1-65535 or 0 for unspecified
      toPort - 1-65535 or 0 for unspecified
    • messageAvailable

      public void messageAvailable(I2PSession session, int msgId, long size)
      For non-muxed.
      Specified by:
      messageAvailable in interface I2PSessionListener
      Specified by:
      messageAvailable in interface I2PSessionMuxedListener
      Parameters:
      session - session to notify
      msgId - message number available
      size - 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

      public void reportAbuse(I2PSession session, int severity)
      Handle a reportAbuse message from the session.
      Specified by:
      reportAbuse in interface I2PSessionListener
      Specified by:
      reportAbuse in interface I2PSessionMuxedListener
      Parameters:
      session - the I2P session that reported the abuse, used only for context
      severity - the abuse severity
    • disconnected

      public void disconnected(I2PSession session)
      Handle a session disconnect.
      Specified by:
      disconnected in interface I2PSessionListener
      Specified by:
      disconnected in interface I2PSessionMuxedListener
      Parameters:
      session - the I2P session that closed
    • errorOccurred

      public void errorOccurred(I2PSession session, String message, Throwable error)
      Handle a session error.
      Specified by:
      errorOccurred in interface I2PSessionListener
      Specified by:
      errorOccurred in interface I2PSessionMuxedListener
      Parameters:
      session - the I2P session that reported the error
      message - the error message
      error - the throwable reported with the error