net.i2p.client.impl

## Class I2PSessionImpl

- java.lang.Object
- - net.i2p.client.impl.I2PSessionImpl

- All Implemented Interfaces:
    I2PSession, I2CPMessageReader.I2CPMessageEventListener
  Direct Known Subclasses:
    I2PSessionImpl2

      public abstract class I2PSessionImpl
      extends Object
      implements I2PSession, I2CPMessageReader.I2CPMessageEventListener

  Implementation of an I2P session running over TCP. This class is NOT thread safe - only one thread should send messages at any given time Public only for clearCache(). Except for methods defined in I2PSession and I2CPMessageEventListener, not maintained as a public API, not for external use. Use I2PClientFactory to get an I2PClient and then createSession().

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `protected class` | `I2PSessionImpl.AvailabilityNotifier` This notifies the client of payload messages.
    `protected static class` | `I2PSessionImpl.State` Session state enumeration.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected I2PSessionImpl.AvailabilityNotifier` | `_availabilityNotifier` thread that we tell when new messages are available who then tells us to fetch them.
    `protected Map<Long,MessagePayloadMessage>` | `_availableMessages` map of Long --> MessagePayloadMessage
    `protected int[]` | `_bwLimits`
    `protected Object` | `_bwReceivedLock`
    `protected I2PAppContext` | `_context` used to separate things out so we can get rid of singletons
    `protected I2PClientMessageHandlerMap` | `_handlerMap`
    `protected String` | `_hostname` hostname of router - will be null if in RouterContext
    `protected LeaseSet` | `_leaseSet` currently granted lease set, or null
    `protected Object` | `_leaseSetWait` monitor for waiting until a lease set has been granted
    `protected Log` | `_log`
    `protected LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter>` | `_pendingLookups` hashes of lookups we are waiting for
    `protected int` | `_portNum` port num to router - will be 0 if in RouterContext
    `protected I2CPMessageProducer` | `_producer` class that generates new messages
    `protected I2CPMessageQueue` | `_queue` Used for internal connections to the router.
    `protected I2CPMessageReader` | `_reader` reader that always searches for messages
    `protected I2PSessionListener` | `_sessionListener` who we send events to
    `protected Socket` | `_socket` socket for comm
    `protected I2PSessionImpl.State` | `_state`
    `protected Object` | `_stateLock`
    `protected SigningPublicKey` | `_transientSigningPublicKey`
    `protected ClientWriterRunner` | `_writer` writer message queue
    `protected static int` | `CACHE_MAX_SIZE`
    `(package private) static SessionId` | `DUMMY_SESSION`
    `static int` | `LISTEN_PORT`
    `protected static String` | `PROP_DOMAIN_SOCKET` Use Unix domain socket (or similar) to connect to a router

    - ### Fields inherited from interface net.i2p.client.I2PSession

      `PORT_ANY, PORT_UNSPECIFIED, PROTO_ANY, PROTO_DATAGRAM, PROTO_DATAGRAM_RAW, PROTO_DATAGRAM2, PROTO_DATAGRAM3, PROTO_STREAMING, PROTO_UNSPECIFIED`

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `` | `I2PSessionImpl(I2PAppContext context, InputStream destKeyStream, Properties options)` Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey from the destKeyStream, and using the specified options to connect to the router As of 0.9.19, defaults in options are honored.
    `protected` | `I2PSessionImpl(I2PAppContext context, Properties options, I2PClientMessageHandlerMap handlerMap)` for extension by SimpleSession (no dest)
    `protected` | `I2PSessionImpl(I2PSessionImpl primary, InputStream destKeyStream, Properties options)`

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addNewMessage(MessagePayloadMessage msg)` Recieve a payload message and let the app know its available
    `I2PSession` | `addSubsession(InputStream privateKeyStream, Properties opts)` Router must be connected or was connected...
    `int[]` | `bandwidthLimits()` Blocking.
    `(package private) void` | `bwReceived(int[] i)` called by the message handler
    `protected void` | `changeState(I2PSessionImpl.State state)`
    `static void` | `clearCache()`
    `void` | `connect()` Connect to the router and establish a session.
    `(package private) void` | `dateUpdated(String routerVersion)`
    `(package private) void` | `destLookupFailed(Hash h)` Called by the message handler on reception of DestReplyMessage
    `(package private) void` | `destLookupFailed(long nonce, int code)` Called by the message handler on reception of HostReplyMessage
    `(package private) void` | `destReceived(Destination d)` Called by the message handler on reception of DestReplyMessage
    `(package private) void` | `destReceived(long nonce, Destination d)` Called by the message handler on reception of HostReplyMessage
    `void` | `destroySession()` Tear down the session, and do NOT reconnect.
    `void` | `destroySession(boolean sendDisconnect)` Tear down the session, and do NOT reconnect.
    `protected void` | `disconnect()` Will interrupt a connect in progress.
    `void` | `disconnected(I2CPMessageReader reader)` The I2CPMessageEventListener callback.
    `(package private) I2PAppContext` | `getContext()` For Subsessions
    `boolean` | `getFastReceive()`
    `(package private) I2PClientMessageHandlerMap` | `getHandlerMap()` For Subsessions
    `(package private) long` | `getLastLS2SignTime()` The published timestamp of the last LS2 we signed
    `(package private) LeaseSet` | `getLeaseSet()`
    `Destination` | `getMyDestination()` Retrieve the destination of the session
    `protected String` | `getName()`
    `long` | `getOfflineExpiration()` Get the offline expiration
    `Signature` | `getOfflineSignature()`
    `(package private) Properties` | `getOptions()` Retrieve the configuration options, filtered.
    `protected String` | `getPrefix()` try hard to make a decent identifier as this will appear in error logs
    `SigningPrivateKey` | `getPrivateKey()` Retrieve the signing SigningPrivateKey.
    `(package private) I2CPMessageProducer` | `getProducer()` Retrieve the helper that generates I2CP messages
    `String` | `getRouterVersion()` Always valid in RouterContext.
    `(package private) SessionId` | `getSessionId()` Retrieve the session's ID
    `List<I2PSession>` | `getSubsessions()`
    `SigningPublicKey` | `getTransientSigningPublicKey()`
    `boolean` | `isClosed()` Has the session been closed (or not yet connected)? False when open and during transitions.
    `boolean` | `isOffline()` Does this session have offline and transient keys?
    `long` | `lastActivity()`
    `Destination` | `lookupDest(Hash h)` Blocking.
    `Destination` | `lookupDest(Hash h, long maxWait)` Blocking.
    `LookupResult` | `lookupDest(Hash h, long maxWait, LookupCallback callback)` Lookup a Destination by hostname.
    `Destination` | `lookupDest(String name)` Ask the router to lookup a Destination by host name.
    `Destination` | `lookupDest(String name, long maxWait)` Ask the router to lookup a Destination by host name.
    `LookupResult` | `lookupDest(String name, long maxWait, LookupCallback callback)` Lookup a Destination by hash.
    `LookupResult` | `lookupDest2(String name, long maxWait)` Ask the router to lookup a Destination by host name.
    `void` | `messageReceived(I2CPMessageReader reader, I2CPMessage message)` The I2CPMessageEventListener callback.
    `(package private) void` | `propagateError(String msg, Throwable error)` Pass off the error to the listener Misspelled, oh well.
    `void` | `readError(I2CPMessageReader reader, Exception error)` The I2CPMessageEventListener callback.
    `byte[]` | `receiveMessage(int msgId)` Pull the unencrypted data from the message that we've already prefetched and notified the user that its available.
    `abstract void` | `receiveStatus(int msgId, long nonce, int status)`
    `protected boolean` | `reconnect()`
    `void` | `removeSubsession(I2PSession session)`
    `void` | `reportAbuse(int msgId, int severity)` Report abuse with regards to the given messageId
    `void` | `sendBlindingInfo(BlindData bd)`
    `(package private) void` | `sendMessage_unchecked(I2CPMessage message)` Deliver an I2CP message to the router.
    `(package private) void` | `sendMessage(I2CPMessage message)` Deliver an I2CP message to the router As of 0.9.3, may block for several seconds if the write queue to the router is full
    `(package private) void` | `setLastLS2SignTime(long now)` The published timestamp of the last LS2 we signed
    `(package private) void` | `setLeaseSet(LeaseSet ls)`
    `void` | `setReduced()`
    `(package private) void` | `setSessionId(SessionId id)`
    `void` | `setSessionListener(I2PSessionListener lsnr)` configure the listener
    `protected boolean` | `shouldReconnect()`
    `protected void` | `startVerifyUsage()` Fire up a periodic task to check for unclaimed messages
    `boolean` | `supportsLS2()`
    `String` | `toString()`
    `protected void` | `updateActivity()`
    `void` | `updateOptions(Properties options)` Update the tunnel and bandwidth settings
    `protected void` | `verifyOpen()` Throws I2PSessionException if uninitialized, closed or closing.
    `protected void` | `waitForDate()`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

    - ### Methods inherited from interface net.i2p.client.I2PSession

      `addMuxedSessionListener, addSessionListener, removeListener, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage`

- - ### Field Detail

    - #### _availabilityNotifier

          protected I2PSessionImpl.AvailabilityNotifier _availabilityNotifier

      thread that we tell when new messages are available who then tells us to fetch them. The point of this is so that the fetch doesn't block the reading of other messages (in turn, potentially leading to deadlock)

    - #### _availableMessages

          protected Map<Long,MessagePayloadMessage> _availableMessages

      map of Long --> MessagePayloadMessage

    - #### _bwLimits

          protected volatile int[] _bwLimits

    - #### _bwReceivedLock

          protected final Object _bwReceivedLock

    - #### _context

          protected final I2PAppContext _context

      used to separate things out so we can get rid of singletons

    - #### _handlerMap

          protected final I2PClientMessageHandlerMap _handlerMap

    - #### _hostname

          protected final String _hostname

      hostname of router - will be null if in RouterContext

    - #### _leaseSet

          protected volatile LeaseSet _leaseSet

      currently granted lease set, or null

    - #### _leaseSetWait

          protected final Object _leaseSetWait

      monitor for waiting until a lease set has been granted

    - #### _log

          protected final Log _log

    - #### _pendingLookups

          protected final LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter> _pendingLookups

      hashes of lookups we are waiting for

    - #### _portNum

          protected final int _portNum

      port num to router - will be 0 if in RouterContext

    - #### _producer

          protected final I2CPMessageProducer _producer

      class that generates new messages

    - #### _queue

          protected I2CPMessageQueue _queue

      Used for internal connections to the router. If this is set, _socket and _writer will be null.

    - #### _reader

          protected I2CPMessageReader _reader

      reader that always searches for messages

    - #### _sessionListener

          protected I2PSessionListener _sessionListener

      who we send events to

    - #### _socket

          protected Socket _socket

      socket for comm

    - #### _state

          protected I2PSessionImpl.State _state

    - #### _stateLock

          protected final Object _stateLock

    - #### _transientSigningPublicKey

          protected SigningPublicKey _transientSigningPublicKey

    - #### _writer

          protected ClientWriterRunner _writer

      writer message queue

    - #### CACHE_MAX_SIZE

          protected static final int CACHE_MAX_SIZE

    - #### DUMMY_SESSION

          static final SessionId DUMMY_SESSION

    - #### LISTEN_PORT

          public static final int LISTEN_PORT

      See Also:
        Constant Field Values

    - #### PROP_DOMAIN_SOCKET

          protected static final String PROP_DOMAIN_SOCKET

      Use Unix domain socket (or similar) to connect to a router
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### I2PSessionImpl

          public I2PSessionImpl(I2PAppContext context,
                                InputStream destKeyStream,
                                Properties options)
                         throws I2PSessionException

      Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey from the destKeyStream, and using the specified options to connect to the router As of 0.9.19, defaults in options are honored. This does NOT validate consistency of the destKeyStream, e.g. pubkey/privkey match or valid offline sig. The router does that.
      Parameters:
        `destKeyStream` - stream containing the private key data, format is specified in `PrivateKeyFile`
        `options` - set of options to configure the router with, if null will use System properties
      Throws:
        `I2PSessionException` - if there is a problem loading the private keys

    - #### I2PSessionImpl

          protected I2PSessionImpl(I2PAppContext context,
                                   Properties options,
                                   I2PClientMessageHandlerMap handlerMap)

      for extension by SimpleSession (no dest)

    - #### I2PSessionImpl

          protected I2PSessionImpl(I2PSessionImpl primary,
                                   InputStream destKeyStream,
                                   Properties options)
                            throws I2PSessionException

      Throws:
        `I2PSessionException`

  - ### Method Detail

    - #### addNewMessage

          public void addNewMessage(MessagePayloadMessage msg)

      Recieve a payload message and let the app know its available

    - #### addSubsession

          public I2PSession addSubsession(InputStream privateKeyStream,
                                          Properties opts)
                                   throws I2PSessionException

      Router must be connected or was connected... for now.
      Specified by:
        `addSubsession` in interface `I2PSession`
      Parameters:
        `privateKeyStream` - null for transient, if non-null must have same encryption keys as primary session and different signing keys
        `opts` - subsession options if any, may be null
      Returns:
        a new subsession, non-null
      Throws:
        `I2PSessionException`

    - #### bandwidthLimits

          public int[] bandwidthLimits()
                                throws I2PSessionException

      Blocking. Waits a max of 5 seconds. But shouldn't take long. Implemented in 0.8.3 in I2PSessionImpl; previously was available only in I2PSimpleSession. Multiple outstanding lookups are now allowed.
      Specified by:
        `bandwidthLimits` in interface `I2PSession`
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### bwReceived

          void bwReceived(int[] i)

      called by the message handler

    - #### changeState

          protected void changeState(I2PSessionImpl.State state)

    - #### clearCache

          public static void clearCache()

    - #### connect

          public void connect()
                       throws I2PSessionException

      Connect to the router and establish a session. This call blocks until a session is granted. Should be threadsafe, other threads will block until complete. Disconnect / destroy from another thread may be called simultaneously and will (should?) interrupt the connect. Connecting a primary session will not automatically connect subsessions. Connecting a subsession will automatically connect the primary session if not previously connected.
      Specified by:
        `connect` in interface `I2PSession`
      Throws:
        `I2PSessionException` - if there is a configuration error or the router is not reachable

    - #### dateUpdated

          void dateUpdated(String routerVersion)

      Parameters:
        `routerVersion` - as rcvd in the SetDateMessage, may be null for very old routers

    - #### destLookupFailed

          void destLookupFailed(Hash h)

      Called by the message handler on reception of DestReplyMessage
      Parameters:
        `h` - non-null

    - #### destLookupFailed

          void destLookupFailed(long nonce,
                                int code)

      Called by the message handler on reception of HostReplyMessage

    - #### destReceived

          void destReceived(Destination d)

      Called by the message handler on reception of DestReplyMessage
      Parameters:
        `d` - non-null

    - #### destReceived

          void destReceived(long nonce,
                            Destination d)

      Called by the message handler on reception of HostReplyMessage
      Parameters:
        `d` - non-null

    - #### destroySession

          public void destroySession()

      Tear down the session, and do NOT reconnect. Blocks if session has not been fully started.
      Specified by:
        `destroySession` in interface `I2PSession`

    - #### destroySession

          public void destroySession(boolean sendDisconnect)

      Tear down the session, and do NOT reconnect. Will interrupt an open in progress. Calls sessionlistener.disconnected()

    - #### disconnect

          protected void disconnect()

      Will interrupt a connect in progress. Calls sessionlistener.disconnected()

    - #### disconnected

          public void disconnected(I2CPMessageReader reader)

      The I2CPMessageEventListener callback. Recieve notification that the I2CP connection was disconnected. Calls sessionlistener.disconnected()
      Specified by:
        `disconnected` in interface `I2CPMessageReader.I2CPMessageEventListener`
      Parameters:
        `reader` - unused

    - #### getContext

          I2PAppContext getContext()

      For Subsessions

    - #### getFastReceive

          public boolean getFastReceive()

    - #### getHandlerMap

          I2PClientMessageHandlerMap getHandlerMap()

      For Subsessions

    - #### getLastLS2SignTime

          long getLastLS2SignTime()

      The published timestamp of the last LS2 we signed
      Returns:
        0 if never

    - #### getLeaseSet

          LeaseSet getLeaseSet()

    - #### getMyDestination

          public Destination getMyDestination()

      Retrieve the destination of the session
      Specified by:
        `getMyDestination` in interface `I2PSession`

    - #### getName

          protected String getName()

    - #### getOfflineExpiration

          public long getOfflineExpiration()

      Description copied from interface: `I2PSession`
      Get the offline expiration
      Specified by:
        `getOfflineExpiration` in interface `I2PSession`
      Returns:
        Java time (ms) or 0 if not initialized or does not have offline keys

    - #### getOfflineSignature

          public Signature getOfflineSignature()

      Specified by:
        `getOfflineSignature` in interface `I2PSession`
      Returns:
        null on error or if not initialized or does not have offline keys

    - #### getOptions

          Properties getOptions()

      Retrieve the configuration options, filtered. All defaults passed in via constructor have been promoted to the primary map.
      Returns:
        non-null, if instantiated with null options, this will be the System properties.

    - #### getPrefix

          protected String getPrefix()

      try hard to make a decent identifier as this will appear in error logs

    - #### getPrivateKey

          public SigningPrivateKey getPrivateKey()

      Retrieve the signing SigningPrivateKey. As of 0.9.38, this will be the transient key if offline signed.
      Specified by:
        `getPrivateKey` in interface `I2PSession`

    - #### getProducer

          I2CPMessageProducer getProducer()

      Retrieve the helper that generates I2CP messages

    - #### getRouterVersion

          public String getRouterVersion()

      Always valid in RouterContext. Returns null if not yet connected in I2PAppContext.
      Specified by:
        `getRouterVersion` in interface `I2PSession`
      Returns:
        null if unknown

    - #### getSessionId

          SessionId getSessionId()

      Retrieve the session's ID
      Returns:
        null if unset

    - #### getSubsessions

          public List<I2PSession> getSubsessions()

      Specified by:
        `getSubsessions` in interface `I2PSession`
      Returns:
        a list of subsessions, non-null, does not include the primary session

    - #### getTransientSigningPublicKey

          public SigningPublicKey getTransientSigningPublicKey()

      Specified by:
        `getTransientSigningPublicKey` in interface `I2PSession`
      Returns:
        null on error or if not initialized or does not have offline keys

    - #### isClosed

          public boolean isClosed()

      Has the session been closed (or not yet connected)? False when open and during transitions. Synchronized.
      Specified by:
        `isClosed` in interface `I2PSession`
      Returns:
        true if the session is closed, OR connect() has not been called yet

    - #### isOffline

          public boolean isOffline()

      Does this session have offline and transient keys?
      Specified by:
        `isOffline` in interface `I2PSession`

    - #### lastActivity

          public long lastActivity()

    - #### lookupDest

          public Destination lookupDest(Hash h)
                                 throws I2PSessionException

      Blocking. Waits a max of 10 seconds by default. See lookupDest with maxWait parameter to change. Implemented in 0.8.3 in I2PSessionImpl; previously was available only in I2PSimpleSession. Multiple outstanding lookups are now allowed.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### lookupDest

          public Destination lookupDest(Hash h,
                                        long maxWait)
                                 throws I2PSessionException

      Blocking.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Parameters:
        `maxWait` - ms
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### lookupDest

          public LookupResult lookupDest(Hash h,
                                         long maxWait,
                                         LookupCallback callback)
                                  throws I2PSessionException

      Lookup a Destination by hostname. Non-blocking. If the result is cached or there is an immediate failure, the result code will be something other than RESULT_DEFERRED, and the callback will NOT be called.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Parameters:
        `maxWait` - ms
        `callback` - to return the result, non-null
      Returns:
        non-null. If result code is RESULT_DEFERRED, callback will be called later
      Throws:
        `I2PSessionException`

    - #### lookupDest

          public Destination lookupDest(String name)
                                 throws I2PSessionException

      Ask the router to lookup a Destination by host name. Blocking. Waits a max of 10 seconds by default. This only makes sense for a b32 hostname, OR outside router context. Inside router context, just query the naming service. Outside router context, this does NOT query the context naming service. Do that first if you expect a local addressbook. This will log a warning for non-b32 in router context. See interface for suggested implementation. Requires router side to be 0.9.11 or higher. If the router is older, this will return null immediately.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Throws:
        `I2PSessionException`

    - #### lookupDest

          public Destination lookupDest(String name,
                                        long maxWait)
                                 throws I2PSessionException

      Ask the router to lookup a Destination by host name. Blocking. See above for details.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Parameters:
        `maxWait` - ms
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### lookupDest

          public LookupResult lookupDest(String name,
                                         long maxWait,
                                         LookupCallback callback)
                                  throws I2PSessionException

      Lookup a Destination by hash. Non-blocking. If the result is cached or there is an immediate failure, the result code will be something other than RESULT_DEFERRED, and the callback will NOT be called.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Parameters:
        `maxWait` - ms
        `callback` - to return the result, non-null
      Returns:
        non-null. If result code is RESULT_DEFERRED, callback will be called later
      Throws:
        `I2PSessionException`

    - #### lookupDest2

          public LookupResult lookupDest2(String name,
                                          long maxWait)
                                   throws I2PSessionException

      Ask the router to lookup a Destination by host name. Blocking. See above for details. Same as lookupDest() but with a failure code in the return value
      Specified by:
        `lookupDest2` in interface `I2PSession`
      Parameters:
        `maxWait` - ms
      Returns:
        non-null
      Throws:
        `I2PSessionException`

    - #### messageReceived

          public void messageReceived(I2CPMessageReader reader,
                                      I2CPMessage message)

      The I2CPMessageEventListener callback. Recieve notification of some I2CP message and handle it if possible. We route the message based on message type AND session ID. The following types never contain a session ID and are not routable to a subsession: BandwidthLimitsMessage, DestReplyMessage The following types may not contain a valid session ID even when intended for a subsession, so we must take special care: SessionStatusMessage
      Specified by:
        `messageReceived` in interface `I2CPMessageReader.I2CPMessageEventListener`
      Parameters:
        `reader` - unused
        `message` - the I2CPMessage

    - #### propagateError

          void propagateError(String msg,
                              Throwable error)

      Pass off the error to the listener Misspelled, oh well. Calls sessionlistener.errorOccurred()
      Parameters:
        `error` - non-null

    - #### readError

          public void readError(I2CPMessageReader reader,
                                Exception error)

      The I2CPMessageEventListener callback. Recieve notifiation of an error reading the I2CP stream. As of 0.9.41, does NOT call sessionlistener.disconnected(), the I2CPMessageReader will call disconnected() also.
      Specified by:
        `readError` in interface `I2CPMessageReader.I2CPMessageEventListener`
      Parameters:
        `reader` - unused
        `error` - non-null

    - #### receiveMessage

          public byte[] receiveMessage(int msgId)
                                throws I2PSessionException

      Pull the unencrypted data from the message that we've already prefetched and notified the user that its available.
      Specified by:
        `receiveMessage` in interface `I2PSession`
      Parameters:
        `msgId` - message to fetch
      Returns:
        unencrypted body of the message, or null if not found
      Throws:
        `I2PSessionException`

    - #### receiveStatus

          public abstract void receiveStatus(int msgId,
                                             long nonce,
                                             int status)

    - #### reconnect

          protected boolean reconnect()

    - #### removeSubsession

          public void removeSubsession(I2PSession session)

      Specified by:
        `removeSubsession` in interface `I2PSession`

    - #### reportAbuse

          public void reportAbuse(int msgId,
                                  int severity)
                           throws I2PSessionException

      Report abuse with regards to the given messageId
      Specified by:
        `reportAbuse` in interface `I2PSession`
      Parameters:
        `msgId` - message that was abusive (or -1 for not message related)
        `severity` - how abusive
      Throws:
        `I2PSessionException`

    - #### sendBlindingInfo

          public void sendBlindingInfo(BlindData bd)
                                throws I2PSessionException

      Specified by:
        `sendBlindingInfo` in interface `I2PSession`
      Throws:
        `I2PSessionException`

    - #### sendMessage_unchecked

          void sendMessage_unchecked(I2CPMessage message)
                              throws I2PSessionException

      Deliver an I2CP message to the router. Does NOT check state. Call only from connect() or other methods that need to send messages when not in OPEN state.
      Throws:
        `I2PSessionException` - if the message is malformed or there is an error writing it out

    - #### sendMessage

          void sendMessage(I2CPMessage message)
                    throws I2PSessionException

      Deliver an I2CP message to the router As of 0.9.3, may block for several seconds if the write queue to the router is full
      Throws:
        `I2PSessionException` - if the message is malformed or there is an error writing it out

    - #### setLastLS2SignTime

          void setLastLS2SignTime(long now)

      The published timestamp of the last LS2 we signed

    - #### setLeaseSet

          void setLeaseSet(LeaseSet ls)

    - #### setReduced

          public void setReduced()

    - #### setSessionId

          void setSessionId(SessionId id)

    - #### setSessionListener

          public void setSessionListener(I2PSessionListener lsnr)

      configure the listener
      Specified by:
        `setSessionListener` in interface `I2PSession`
      Parameters:
        `lsnr` - listener to retrieve events

    - #### shouldReconnect

          protected boolean shouldReconnect()

    - #### startVerifyUsage

          protected void startVerifyUsage()

      Fire up a periodic task to check for unclaimed messages

    - #### supportsLS2

          public boolean supportsLS2()

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`

    - #### updateActivity

          protected void updateActivity()

    - #### updateOptions

          public void updateOptions(Properties options)

      Update the tunnel and bandwidth settings
      Specified by:
        `updateOptions` in interface `I2PSession`
      Parameters:
        `options` - non-null

    - #### verifyOpen

          protected void verifyOpen()
                             throws I2PSessionException

      Throws I2PSessionException if uninitialized, closed or closing. Blocks if opening.
      Throws:
        `I2PSessionException`

    - #### waitForDate

          protected void waitForDate()
                              throws InterruptedException,
                                     IOException

      Throws:
        `InterruptedException`
        `IOException`