net.i2p.client

## Class I2PSessionImpl

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

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

      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
  Author:
    jrandom

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `protected class` | `I2PSessionImpl.AvailabilityNotifier` This notifies the client of payload messages.
    `protected class` | `I2PSessionImpl.VerifyUsage`

  - ### 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 boolean` | `_closed` whether the session connection has already been closed (or not yet opened)
    `protected boolean` | `_closing` whether the session connection is in the process of being closed
    `protected I2PAppContext` | `_context` used to seperate 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 Log` | `_log`
    `protected boolean` | `_opening` whether the session connection is in the process of being opened
    `protected OutputStream` | `_out` where we pipe our messages
    `protected LinkedBlockingQueue<net.i2p.client.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 ClientWriterRunner` | `_writer` writer message queue
    `static int` | `LISTEN_PORT`
    `protected static String` | `PROP_ENABLE_SSL` SSL interface (only) @since 0.8.3

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

      `PORT_ANY, PORT_UNSPECIFIED, PROTO_ANY, PROTO_DATAGRAM, PROTO_STREAMING, PROTO_UNSPECIFIED`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `I2PSessionImpl()` for extension
    `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

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addNewMessage(MessagePayloadMessage msg)` Recieve a payload message and let the app know its available
    `int[]` | `bandwidthLimits()` Blocking.
    `(package private) void` | `bwReceived(int[] i)` called by the message handler
    `void` | `connect()` Connect to the router and establish a session.
    `(package private) void` | `dateUpdated()`
    `(package private) void` | `destLookupFailed(Hash h)` called by the message handler
    `(package private) void` | `destReceived(Destination d)` called by the message handler
    `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()`
    `void` | `disconnected(I2CPMessageReader reader)` The I2CPMessageEventListener callback.
    `PrivateKey` | `getDecryptionKey()` Retrieve the decryption PrivateKey
    `(package private) LeaseSet` | `getLeaseSet()`
    `Destination` | `getMyDestination()` Retrieve the destination of the session
    `(package private) boolean` | `getOpening()`
    `(package private) Properties` | `getOptions()` Retrieve the configuration options
    `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
    `(package private) SessionId` | `getSessionId()` Retrieve the session's ID
    `boolean` | `isClosed()` has the session been closed (or not yet connected)?
    `long` | `lastActivity()`
    `protected void` | `loadConfig(Properties options)` Parse the config for anything we know about.
    `Destination` | `lookupDest(Hash h)` Blocking.
    `Destination` | `lookupDest(Hash h, long maxWait)` Blocking.
    `void` | `messageReceived(I2CPMessageReader reader, I2CPMessage message)` The I2CPMessageEventListener callback.
    `(package private) void` | `propogateError(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` | `reportAbuse(int msgId, int severity)` Report abuse with regards to the given messageId
    `(package private) void` | `sendMessage(I2CPMessage message)` Deliver an I2CP message to the router
    `(package private) void` | `setLeaseSet(LeaseSet ls)`
    `(package private) void` | `setOpening(boolean ls)`
    `void` | `setReduced()`
    `(package private) void` | `setSessionId(SessionId id)`
    `void` | `setSessionListener(I2PSessionListener lsnr)` configure the listener
    `protected boolean` | `shouldReconnect()`
    `String` | `toString()`
    `protected void` | `updateActivity()`
    `void` | `updateOptions(Properties options)` Update the tunnel and bandwidth settings

    - ### 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`

- - ### Field Detail

    - #### _log

          protected Log _log

    - #### _hostname

          protected String _hostname

      hostname of router - will be null if in RouterContext

    - #### _portNum

          protected int _portNum

      port num to router - will be 0 if in RouterContext

    - #### _socket

          protected Socket _socket

      socket for comm

    - #### _reader

          protected I2CPMessageReader _reader

      reader that always searches for messages

    - #### _writer

          protected ClientWriterRunner _writer

      writer message queue

    - #### _out

          protected OutputStream _out

      where we pipe our messages

    - #### _queue

          protected I2CPMessageQueue _queue

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

    - #### _sessionListener

          protected I2PSessionListener _sessionListener

      who we send events to

    - #### _producer

          protected I2CPMessageProducer _producer

      class that generates new messages

    - #### _availableMessages

          protected Map<Long,MessagePayloadMessage> _availableMessages

      map of Long --> MessagePayloadMessage

    - #### _pendingLookups

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

      hashes of lookups we are waiting for

    - #### _bwReceivedLock

          protected final Object _bwReceivedLock

    - #### _bwLimits

          protected int[] _bwLimits

    - #### _handlerMap

          protected I2PClientMessageHandlerMap _handlerMap

    - #### _context

          protected I2PAppContext _context

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

    - #### _closed

          protected boolean _closed

      whether the session connection has already been closed (or not yet opened)

    - #### _closing

          protected boolean _closing

      whether the session connection is in the process of being closed

    - #### _opening

          protected boolean _opening

      whether the session connection is in the process of being opened

    - #### _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)

    - #### PROP_ENABLE_SSL

          protected static final String PROP_ENABLE_SSL

      SSL interface (only) @since 0.8.3
      See Also:
        Constant Field Values

    - #### LISTEN_PORT

          public static final int LISTEN_PORT

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### I2PSessionImpl

          public I2PSessionImpl()

      for extension

    - #### 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
      Parameters:
        `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 or

  - ### Method Detail

    - #### dateUpdated

          void dateUpdated()

    - #### loadConfig

          protected void loadConfig(Properties options)

      Parse the config for anything we know about. Also fill in the authorization properties if missing.

    - #### updateOptions

          public void updateOptions(Properties options)

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

    - #### setLeaseSet

          void setLeaseSet(LeaseSet ls)

    - #### getLeaseSet

          LeaseSet getLeaseSet()

    - #### setOpening

          void setOpening(boolean ls)

    - #### getOpening

          boolean getOpening()

    - #### connect

          public void connect()
                       throws I2PSessionException

      Connect to the router and establish a session. This call blocks until a session is granted.
      Specified by:
        `connect` in interface `I2PSession`
      Throws:
        `I2PSessionException` - if there is a configuration error or the router is not reachable

    - #### 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`

    - #### 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`

    - #### receiveStatus

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

    - #### addNewMessage

          public void addNewMessage(MessagePayloadMessage msg)

      Recieve a payload message and let the app know its available

    - #### messageReceived

          public void messageReceived(I2CPMessageReader reader,
                             I2CPMessage message)

      The I2CPMessageEventListener callback. Recieve notification of some I2CP message and handle it if possible.
      Specified by:
        `messageReceived` in interface `I2CPMessageReader.I2CPMessageEventListener`
      Parameters:
        `reader` - unused
        `message` - the I2CPMessage

    - #### readError

          public void readError(I2CPMessageReader reader,
                       Exception error)

      The I2CPMessageEventListener callback. Recieve notifiation of an error reading the I2CP stream.
      Specified by:
        `readError` in interface `I2CPMessageReader.I2CPMessageEventListener`
      Parameters:
        `reader` - unused
        `error` - non-null

    - #### getMyDestination

          public Destination getMyDestination()

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

    - #### getDecryptionKey

          public PrivateKey getDecryptionKey()

      Retrieve the decryption PrivateKey
      Specified by:
        `getDecryptionKey` in interface `I2PSession`

    - #### getPrivateKey

          public SigningPrivateKey getPrivateKey()

      Retrieve the signing SigningPrivateKey
      Specified by:
        `getPrivateKey` in interface `I2PSession`

    - #### getProducer

          I2CPMessageProducer getProducer()

      Retrieve the helper that generates I2CP messages

    - #### getOptions

          Properties getOptions()

      Retrieve the configuration options
      Returns:
        non-null, if insantiated with null options, this will be the System properties.

    - #### getSessionId

          SessionId getSessionId()

      Retrieve the session's ID

    - #### 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

    - #### isClosed

          public boolean isClosed()

      has the session been closed (or not yet connected)?
      Specified by:
        `isClosed` in interface `I2PSession`
      Returns:
        true if the session is closed

    - #### sendMessage

          void sendMessage(I2CPMessage message)
                     throws I2PSessionException

      Deliver an I2CP message to the router
      Throws:
        `I2PSessionException` - if the message is malformed or there is an error writing it out

    - #### propogateError

          void propogateError(String msg,
                            Throwable error)

      Pass off the error to the listener Misspelled, oh well.
      Parameters:
        `error` - 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. Blocks if session has not been fully started.

    - #### disconnected

          public void disconnected(I2CPMessageReader reader)

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

    - #### disconnect

          protected void disconnect()

    - #### shouldReconnect

          protected boolean shouldReconnect()

    - #### reconnect

          protected boolean reconnect()

    - #### getPrefix

          protected String getPrefix()

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

    - #### destReceived

          void destReceived(Destination d)

      called by the message handler

    - #### destLookupFailed

          void destLookupFailed(Hash h)

      called by the message handler

    - #### bwReceived

          void bwReceived(int[] i)

      called by the message handler

    - #### 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`
      Since:
        0.8.3

    - #### 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`

    - #### updateActivity

          protected void updateActivity()

    - #### lastActivity

          public long lastActivity()

    - #### setReduced

          public void setReduced()

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`