net.i2p.client.impl

## Class SubSession

- java.lang.Object
- - net.i2p.client.impl.I2PSessionImpl
  - - net.i2p.client.impl.I2PSessionImpl2
    - - net.i2p.client.impl.I2PSessionMuxedImpl
      - - net.i2p.client.impl.SubSession

- All Implemented Interfaces:
    I2PSession, I2CPMessageReader.I2CPMessageEventListener

      class SubSession
      extends I2PSessionMuxedImpl

  An additional session using another session's connection. A subsession uses the same connection to the router as the primary session, but has a different Destination. It uses the same tunnels as the primary but has its own leaseset. It must use the same encryption keys as the primary so that garlic encryption/decryption works. The message handler map and message producer are reused from primary. Does NOT reuse the session listener ???? While the I2CP protocol, in theory, allows for fully independent sessions over the same I2CP connection, this is not currently supported by the router.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from class net.i2p.client.impl.I2PSessionMuxedImpl

      `I2PSessionMuxedImpl.MuxedAvailabilityNotifier`

    - ### Nested classes/interfaces inherited from class net.i2p.client.impl.I2PSessionImpl

      `I2PSessionImpl.AvailabilityNotifier, I2PSessionImpl.State`

  - ### Field Summary

    - ### Fields inherited from class net.i2p.client.impl.I2PSessionImpl2

      `_noEffort, _sendingStates, _sendMessageNonce`

    - ### Fields inherited from class net.i2p.client.impl.I2PSessionImpl

      `_availabilityNotifier, _availableMessages, _bwLimits, _bwReceivedLock, _context, _handlerMap, _hostname, _leaseSet, _leaseSetWait, _log, _pendingLookups, _portNum, _producer, _queue, _reader, _sessionListener, _socket, _state, _stateLock, _transientSigningPublicKey, _writer, CACHE_MAX_SIZE, DUMMY_SESSION, LISTEN_PORT, PROP_DOMAIN_SOCKET`

    - ### 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
    Constructor and Description
    `SubSession(I2PSession primary, InputStream destKeyStream, Properties options)`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `I2PSession` | `addSubsession(InputStream destKeyStream, Properties opts)` Unsupported in a subsession.
    `int[]` | `bandwidthLimits()` This won't be called, as the reply does not contain a session ID, so it won't be routed back to us
    `(package private) void` | `bwReceived(int[] i)` Called by the message handler.
    `void` | `connect()` Connect to the router and establish a session.
    `(package private) void` | `destLookupFailed(Hash h)` Called by the message handler on reception of DestReplyMessage This will never happen, as the dest reply message does not contain a session ID.
    `(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 This will never happen, as the dest reply message does not contain a session ID.
    `(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.
    `protected void` | `disconnect()` Will interrupt a connect in progress.
    `Properties` | `getPrimaryOptions()`
    `List<I2PSession>` | `getSubsessions()` Unsupported in a subsession.
    `boolean` | `isClosed()` Has the session been closed (or not yet connected)? False when open and during transitions.
    `long` | `lastActivity()`
    `Destination` | `lookupDest(Hash h)` Blocking.
    `Destination` | `lookupDest(Hash h, long maxWait)` Blocking.
    `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.
    `(package private) void` | `propagateError(String msg, Throwable error)` Pass off the error to the listener Misspelled, oh well.
    `protected boolean` | `reconnect()` Called whenever we want to reconnect (used only in the superclass).
    `void` | `removeSubsession(I2PSession session)` Unsupported in a subsession.
    `(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 May block for several seconds if the write queue to the router is full
    `void` | `setReduced()`
    `protected void` | `updateActivity()`
    `void` | `updateOptions(Properties options)` Does nothing for now

    - ### Methods inherited from class net.i2p.client.impl.I2PSessionMuxedImpl

      `addMuxedSessionListener, addNewMessage, addSessionListener, removeListener, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, setSessionListener`

    - ### Methods inherited from class net.i2p.client.impl.I2PSessionImpl2

      `destroySession, getTimeout, receiveMessage, receiveStatus, sendBestEffort, sendBestEffort, sendMessage, sendMessage, sendMessage, sendNoEffort, shouldCompress, startVerifyUsage`

    - ### Methods inherited from class net.i2p.client.impl.I2PSessionImpl

      `changeState, clearCache, dateUpdated, disconnected, getContext, getFastReceive, getHandlerMap, getLastLS2SignTime, getLeaseSet, getMyDestination, getName, getOfflineExpiration, getOfflineSignature, getOptions, getPrefix, getPrivateKey, getProducer, getRouterVersion, getSessionId, getTransientSigningPublicKey, isOffline, lookupDest, lookupDest, lookupDest2, messageReceived, readError, reportAbuse, sendBlindingInfo, setLastLS2SignTime, setLeaseSet, setSessionId, shouldReconnect, supportsLS2, toString, verifyOpen, waitForDate`

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

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

- - ### Constructor Detail

    - #### SubSession

          public SubSession(I2PSession primary,
                            InputStream destKeyStream,
                            Properties options)
                     throws I2PSessionException

      Parameters:
        `primary` - must be a I2PSessionMuxedImpl
      Throws:
        `I2PSessionException`

  - ### Method Detail

    - #### addSubsession

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

      Unsupported in a subsession.
      Specified by:
        `addSubsession` in interface `I2PSession`
      Overrides:
        `addSubsession` in class `I2PSessionImpl`
      Parameters:
        `destKeyStream` - 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:
        `UnsupportedOperationException` - always
        `I2PSessionException`

    - #### bandwidthLimits

          public int[] bandwidthLimits()
                                throws I2PSessionException

      This won't be called, as the reply does not contain a session ID, so it won't be routed back to us
      Specified by:
        `bandwidthLimits` in interface `I2PSession`
      Overrides:
        `bandwidthLimits` in class `I2PSessionImpl`
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### bwReceived

          void bwReceived(int[] i)

      Called by the message handler. This will never happen, as the bw limits message does not contain a session ID.
      Overrides:
        `bwReceived` in class `I2PSessionImpl`

    - #### 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 subsession will automatically connect the primary session if not previously connected.
      Specified by:
        `connect` in interface `I2PSession`
      Overrides:
        `connect` in class `I2PSessionImpl`
      Throws:
        `I2PSessionException` - if there is a configuration error or the router is not reachable

    - #### destLookupFailed

          void destLookupFailed(Hash h)

      Called by the message handler on reception of DestReplyMessage This will never happen, as the dest reply message does not contain a session ID.
      Overrides:
        `destLookupFailed` in class `I2PSessionImpl`
      Parameters:
        `h` - non-null

    - #### destLookupFailed

          void destLookupFailed(long nonce,
                                int code)

      Called by the message handler on reception of HostReplyMessage
      Overrides:
        `destLookupFailed` in class `I2PSessionImpl`

    - #### destReceived

          void destReceived(Destination d)

      Called by the message handler on reception of DestReplyMessage This will never happen, as the dest reply message does not contain a session ID.
      Overrides:
        `destReceived` in class `I2PSessionImpl`
      Parameters:
        `d` - non-null

    - #### destReceived

          void destReceived(long nonce,
                            Destination d)

      Called by the message handler on reception of HostReplyMessage
      Overrides:
        `destReceived` in class `I2PSessionImpl`
      Parameters:
        `d` - non-null

    - #### destroySession

          public void destroySession()

      Tear down the session, and do NOT reconnect. As of 0.9.67, this does NOT destroy the primary session. Blocks if session has not been fully started.
      Specified by:
        `destroySession` in interface `I2PSession`
      Overrides:
        `destroySession` in class `I2PSessionImpl`

    - #### disconnect

          protected void disconnect()

      Will interrupt a connect in progress.
      Overrides:
        `disconnect` in class `I2PSessionImpl`

    - #### getPrimaryOptions

          public Properties getPrimaryOptions()

    - #### getSubsessions

          public List<I2PSession> getSubsessions()

      Unsupported in a subsession.
      Specified by:
        `getSubsessions` in interface `I2PSession`
      Overrides:
        `getSubsessions` in class `I2PSessionImpl`
      Returns:
        empty list always

    - #### isClosed

          public boolean isClosed()

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

    - #### lastActivity

          public long lastActivity()

      Overrides:
        `lastActivity` in class `I2PSessionImpl`

    - #### 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`
      Overrides:
        `lookupDest` in class `I2PSessionImpl`
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### lookupDest

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

      Blocking.
      Specified by:
        `lookupDest` in interface `I2PSession`
      Overrides:
        `lookupDest` in class `I2PSessionImpl`
      Parameters:
        `maxWait` - ms
      Returns:
        null on failure
      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`
      Overrides:
        `lookupDest` in class `I2PSessionImpl`
      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`
      Overrides:
        `lookupDest` in class `I2PSessionImpl`
      Parameters:
        `maxWait` - ms
      Returns:
        null on failure
      Throws:
        `I2PSessionException`

    - #### propagateError

          void propagateError(String msg,
                              Throwable error)

      Pass off the error to the listener Misspelled, oh well.
      Overrides:
        `propagateError` in class `I2PSessionImpl`
      Parameters:
        `error` - non-null

    - #### reconnect

          protected boolean reconnect()

      Description copied from class: `I2PSessionImpl2`
      Called whenever we want to reconnect (used only in the superclass). We need to override this to clear out the message state
      Overrides:
        `reconnect` in class `I2PSessionImpl2`

    - #### removeSubsession

          public void removeSubsession(I2PSession session)

      Unsupported in a subsession. Does nothing.
      Specified by:
        `removeSubsession` in interface `I2PSession`
      Overrides:
        `removeSubsession` in class `I2PSessionImpl`

    - #### 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.
      Overrides:
        `sendMessage_unchecked` in class `I2PSessionImpl`
      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 May block for several seconds if the write queue to the router is full
      Overrides:
        `sendMessage` in class `I2PSessionImpl`
      Throws:
        `I2PSessionException` - if the message is malformed or there is an error writing it out

    - #### setReduced

          public void setReduced()

      Overrides:
        `setReduced` in class `I2PSessionImpl`

    - #### updateActivity

          protected void updateActivity()

      Overrides:
        `updateActivity` in class `I2PSessionImpl`

    - #### updateOptions

          public void updateOptions(Properties options)

      Does nothing for now
      Specified by:
        `updateOptions` in interface `I2PSession`
      Overrides:
        `updateOptions` in class `I2PSessionImpl`
      Parameters:
        `options` - non-null