All Known Implementing Classes:
I2PSessionImpl, I2PSessionImpl2, I2PSessionMuxedImpl, I2PSimpleSession, SubSession

public interface I2PSession

Define the standard means of sending and receiving messages on the I2P network by using the I2CP (the client protocol). This is done over a bidirectional TCP socket.

End to end encryption in I2PSession was disabled in release 0.6.

Periodically the router will ask the client to authorize a new set of tunnels to be allocated to the client, which the client can accept by sending a LeaseSet signed by the Destination. In addition, the router may on occasion provide the client with an updated clock offset so that the client can stay in sync with the network (even if the host computer's clock is off).

  • Field Details

    • PORT_ANY

      static final int PORT_ANY
      Any port.
      See Also:
    • PORT_UNSPECIFIED

      static final int PORT_UNSPECIFIED
      Unspecified port.
      See Also:
    • PROTO_ANY

      static final int PROTO_ANY
      Any protocol.
      See Also:
    • PROTO_UNSPECIFIED

      static final int PROTO_UNSPECIFIED
      Unspecified protocol.
      See Also:
    • PROTO_STREAMING

      static final int PROTO_STREAMING
      Streaming protocol.
      See Also:
    • PROTO_DATAGRAM

      static final int PROTO_DATAGRAM
      A repliable and signed datagram.
      See Also:
    • PROTO_DATAGRAM_RAW

      static final int PROTO_DATAGRAM_RAW
      A raw (unsigned, unrepliable) datagram.
      See Also:
    • PROTO_DATAGRAM2

      static final int PROTO_DATAGRAM2
      A repliable and signed datagram. See Proposal 163 and datagrams/Datagram2.
      See Also:
    • PROTO_DATAGRAM3

      static final int PROTO_DATAGRAM3
      A repliable but unsigned datagram. See Proposal 163 and datagrams/Datagram3.
      See Also:
  • Method Details

    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException
      Send a new message to the given destination, containing the specified payload, returning true if the router feels confident that the message was delivered.

      WARNING: It is recommended that you use a method that specifies the protocol and ports.

      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      Returns:
      whether it was accepted by the router for delivery or not
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size) throws I2PSessionException
      Send a new message to the given destination, containing the specified payload, returning true if the router feels confident that the message was delivered.

      WARNING: It is recommended that you use a method that specifies the protocol and ports.

      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int proto, int fromport, int toport) throws I2PSessionException
      See I2PSessionMuxedImpl for proto/port details.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      proto - 1-254, or 0 for unset; 255 disallowed
      fromport - source port, 1-65535 or 0 for unset
      toport - destination port, 1-65535 or 0 for unset
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set<SessionTag> tagsSent) throws I2PSessionException
      End-to-End Crypto is disabled, tags and keys are ignored!

      Like sendMessage above, except the key used and the tags sent are exposed to the application.

      If some application layer message delivery confirmation is used, rather than i2p's (slow) built in confirmation via guaranteed delivery mode, the application can update the SessionKeyManager, ala:

       SessionKeyManager.getInstance().tagsDelivered(dest.getPublicKey(), keyUsed, tagsSent);
      
      If an application is using guaranteed delivery mode, this is not useful, but for applications using best effort delivery mode, if they can know with certainty that a message was delivered and can update the SessionKeyManager appropriately, a significant performance boost will occur (subsequent message encryption and decryption will be done via AES and a SessionTag, rather than ElGamal+AES, which is 1000x slower).
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      keyUsed - UNUSED, IGNORED. Session key delivered to the destination for association with the tags sent. This is essentially an output parameter - keyUsed.getData() is ignored during this call, but after the call completes, it will be filled with the bytes of the session key delivered. Typically the key delivered is the same one as the key encrypted with, but not always. If this is null then the key data will not be exposed.
      tagsSent - UNUSED, IGNORED. Set of tags delivered to the peer and associated with the keyUsed. This is also an output parameter - the contents of the set is ignored during the call, but afterwards it contains a set of SessionTag objects that were sent along side the given keyUsed.
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set<SessionTag> tagsSent) throws I2PSessionException
      End-to-End Crypto is disabled, tags and keys are ignored.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      keyUsed - UNUSED, IGNORED, as end-to-end crypto is disabled
      tagsSent - UNUSED, IGNORED, as end-to-end crypto is disabled
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set<SessionTag> tagsSent, long expire) throws I2PSessionException
      End-to-End Crypto is disabled, tags and keys are ignored.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      keyUsed - UNUSED, IGNORED, as end-to-end crypto is disabled
      tagsSent - UNUSED, IGNORED, as end-to-end crypto is disabled
      expire - absolute expiration timestamp, NOT interval from now
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set<SessionTag> tagsSent, int proto, int fromPort, int toPort) throws I2PSessionException
      See I2PSessionMuxedImpl for proto/port details. End-to-End Crypto is disabled, tags and keys are ignored.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      keyUsed - UNUSED, IGNORED, as end-to-end crypto is disabled
      tagsSent - UNUSED, IGNORED, as end-to-end crypto is disabled
      proto - 1-254 or 0 for unset; recommended: I2PSession.PROTO_UNSPECIFIED I2PSession.PROTO_STREAMING I2PSession.PROTO_DATAGRAM 255 disallowed
      fromPort - 1-65535 or 0 for unset
      toPort - 1-65535 or 0 for unset
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set<SessionTag> tagsSent, long expire, int proto, int fromPort, int toPort) throws I2PSessionException
      See I2PSessionMuxedImpl for proto/port details. End-to-End Crypto is disabled, tags and keys are ignored.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      keyUsed - UNUSED, IGNORED, as end-to-end crypto is disabled
      tagsSent - UNUSED, IGNORED, as end-to-end crypto is disabled
      expire - absolute expiration timestamp, NOT interval from now
      proto - 1-254 or 0 for unset; recommended: I2PSession.PROTO_UNSPECIFIED I2PSession.PROTO_STREAMING I2PSession.PROTO_DATAGRAM 255 disallowed
      fromPort - 1-65535 or 0 for unset
      toPort - 1-65535 or 0 for unset
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set<SessionTag> tagsSent, long expire, int proto, int fromPort, int toPort, int flags) throws I2PSessionException
      See I2PSessionMuxedImpl for proto/port details. End-to-End Crypto is disabled, tags and keys are ignored.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      keyUsed - UNUSED, IGNORED, as end-to-end crypto is disabled
      tagsSent - UNUSED, IGNORED, as end-to-end crypto is disabled
      expire - absolute expiration timestamp, NOT interval from now
      proto - 1-254 or 0 for unset; recommended: I2PSession.PROTO_UNSPECIFIED I2PSession.PROTO_STREAMING I2PSession.PROTO_DATAGRAM 255 disallowed
      fromPort - 1-65535 or 0 for unset
      toPort - 1-65535 or 0 for unset
      flags - packed SendMessageOptions bits to send with the message
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      boolean sendMessage(Destination dest, byte[] payload, int offset, int size, int proto, int fromPort, int toPort, SendMessageOptions options) throws I2PSessionException
      See I2PSessionMuxedImpl for proto/port details. See SendMessageOptions for option details.
      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      proto - 1-254 or 0 for unset; recommended: I2PSession.PROTO_UNSPECIFIED I2PSession.PROTO_STREAMING I2PSession.PROTO_DATAGRAM 255 disallowed
      fromPort - 1-65535 or 0 for unset
      toPort - 1-65535 or 0 for unset
      options - to be passed to the router
      Returns:
      whether the router accepted the message for delivery
      Throws:
      I2PSessionException - if the session is not open or closed, or the write queue stays full
    • sendMessage

      long sendMessage(Destination dest, byte[] payload, int offset, int size, int proto, int fromPort, int toPort, SendMessageOptions options, SendMessageStatusListener listener) throws I2PSessionException
      Send a message and request an asynchronous notification of delivery status. Notifications will be delivered at least up to the expiration specified in the options, or 60 seconds if not specified.

      See I2PSessionMuxedImpl for proto/port details. See SendMessageOptions for option details.

      Parameters:
      dest - location to send the message
      payload - body of the message to be sent (unencrypted)
      offset - offset into the payload
      size - number of bytes to send
      proto - 1-254 or 0 for unset; recommended: I2PSession.PROTO_UNSPECIFIED I2PSession.PROTO_STREAMING I2PSession.PROTO_DATAGRAM 255 disallowed
      fromPort - 1-65535 or 0 for unset
      toPort - 1-65535 or 0 for unset
      options - to be passed to the router
      listener - for delivery status notification
      Returns:
      the message ID to be used for later notification to the listener
      Throws:
      I2PSessionException - on all errors
    • receiveMessage

      byte[] receiveMessage(int msgId) throws I2PSessionException
      Receive a message that the router has notified the client about, returning the payload. This may only be called once for a given msgId (until the counter wraps).
      Parameters:
      msgId - message to fetch
      Returns:
      unencrypted body of the message, or null if not found
      Throws:
      I2PSessionException - declared but never thrown; failures return null instead
    • discardMessage

      void discardMessage(int msgId)
      Throw away the received message, we don't want it. Use instead of receiveMessage(int) to avoid gunzip overhead.
      Parameters:
      msgId - message whose payload should be dropped rather than returned
    • reportAbuse

      void reportAbuse(int msgId, int severity) throws I2PSessionException
      Instruct the router that the message received was abusive (including how abusive on a 1-100 scale) in the hopes the router can do something to minimize receiving abusive messages like that in the future.

      Unused. Not fully implemented.

      Parameters:
      msgId - message that was abusive (or -1 for not message related)
      severity - abuse rating from 1 (mildest) to 100 (worst)
      Throws:
      I2PSessionException - if the session is not open or closed
    • setSessionListener

      void setSessionListener(I2PSessionListener lsnr)
      Instruct the I2PSession where it should send event notifications

      WARNING: It is recommended that you use a method that specifies the protocol and ports.

      Parameters:
      lsnr - listener to retrieve events
    • destroySession

      void destroySession() throws I2PSessionException
      Tear down the session and release any resources.
      Throws:
      I2PSessionException - declared but never thrown; errors are logged instead
    • addSubsession

      I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException
      Add a subsession.
      Parameters:
      privateKeyStream - null for transient, if non-null must have same encryption keys as primary session
      opts - subsession options if any, may be null
      Returns:
      a new subsession, non-null
      Throws:
      I2PSessionException - if the router does not support sub-sessions, or a sub-session request is pending or the same key was already added
    • removeSubsession

      void removeSubsession(I2PSession session)
      Remove a subsession.
      Parameters:
      session - the subsession to remove
    • getSubsessions

      List<I2PSession> getSubsessions()
      Get the list of subsessions.
      Returns:
      a list of subsessions, non-null, does not include the primary session
    • connect

      void connect() throws I2PSessionException
      Actually connect the session and start receiving/sending messages. Connecting a primary session will not automatically connect subsessions. Connecting a subsession will automatically connect the primary session if not previously connected.
      Throws:
      I2PSessionException - if the router cannot be reached or the session closes mid-connect, or the calling thread is interrupted
    • isClosed

      boolean isClosed()
      Have we closed the session?
      Returns:
      true if the session is closed, OR connect() has not been called yet
    • getMyDestination

      Destination getMyDestination()
      Retrieve the Destination this session serves as the endpoint for. Returns null if no destination is available.
      Returns:
      the Destination, or null
    • getDecryptionKey

      PrivateKey getDecryptionKey()
      Retrieve the decryption PrivateKey associated with the Destination. Obsolete — retained for PrivateKeyFile compatibility.
      Returns:
      the decryption key
    • getPrivateKey

      SigningPrivateKey getPrivateKey()
      Retrieve the signing SigningPrivateKey associated with the Destination. As of 0.9.38, this will be the transient key if offline signed.
      Returns:
      the signing key
    • isOffline

      boolean isOffline()
      Does this session have offline and transient keys?
      Returns:
      true if offline
    • getOfflineExpiration

      long getOfflineExpiration()
      Get the offline expiration.
      Returns:
      Java time (ms) or 0 if not initialized or does not have offline keys
    • getOfflineSignature

      Signature getOfflineSignature()
      Get the offline signature.
      Returns:
      null on error or if not initialized or does not have offline keys
    • getTransientSigningPublicKey

      SigningPublicKey getTransientSigningPublicKey()
      Get the transient signing public key.
      Returns:
      null on error or if not initialized or does not have offline keys
    • lookupDest

      Destination lookupDest(Hash h) throws I2PSessionException
      Lookup a Destination by Hash. Blocking. Waits a max of 10 seconds by default.
      Parameters:
      h - the hash to look up
      Returns:
      the Destination, or null on failure
      Throws:
      I2PSessionException - if the calling thread is interrupted while waiting
    • lookupDest

      Destination lookupDest(Hash h, long maxWait) throws I2PSessionException
      Lookup a Destination by Hash. Blocking.
      Parameters:
      h - the hash to look up
      maxWait - milliseconds to wait for the router's reply before giving up
      Returns:
      null on failure
      Throws:
      I2PSessionException - if the calling thread is interrupted while waiting
    • lookupDest

      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.

      Suggested implementation:

       if (name.length() == 60 && name.toLowerCase(Locale.US).endsWith(".b32.i2p")) {
           if (session != null)
               return session.lookup(Hash.create(Base32.decode(name.toLowerCase(Locale.US).substring(0, 52))));
           else
               return ctx.namingService().lookup(name); // simple session for xxx.b32.i2p handled by naming service (optional if you need lookup w/o an existing session)
       } else if (ctx.isRouterContext()) {
           return ctx.namingService().lookup(name); // hostname from router's naming service
       } else {
           Destination d = ctx.namingService().lookup(name); // local naming svc, optional
           if (d != null)
               return d;
           if (session != null)
               return session.lookup(name);
           // simple session (optional if you need lookup w/o an existing session)
           Destination rv = null;
           I2PClient client = new I2PSimpleClient();
           Properties opts = new Properties();
           opts.put(I2PClient.PROP_TCP_HOST, host);
           opts.put(I2PClient.PROP_TCP_PORT, port);
           I2PSession session = null;
           try {
               session = client.createSession(null, opts);
               session.connect();
               rv = session.lookupDest(name);
           } finally {
               if (session != null)
                   session.destroySession();
           }
           return rv;
       }
      

      Requires router side to be 0.9.11 or higher. If the router is older, this will return null immediately.

      Parameters:
      name - the hostname to look up
      Returns:
      the Destination, or null on failure
      Throws:
      I2PSessionException - if the calling thread is interrupted while waiting
    • lookupDest

      Destination lookupDest(String name, long maxWait) throws I2PSessionException
      Ask the router to lookup a Destination by host name. Blocking. See above for details.
      Parameters:
      name - the hostname to look up
      maxWait - milliseconds to wait for the router's reply before giving up
      Returns:
      null on failure
      Throws:
      I2PSessionException - if the calling thread is interrupted while waiting
    • lookupDest2

      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(Hash) but with a failure code in the return value.
      Parameters:
      name - the hostname to look up
      maxWait - milliseconds to wait for the router's reply before giving up
      Returns:
      non-null
      Throws:
      I2PSessionException - if the calling thread is interrupted while waiting
    • lookupDest

      LookupResult lookupDest(Hash h, 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.
      Parameters:
      h - the hash to look up
      maxWait - milliseconds to wait for the router's reply before giving up
      callback - to return the result, non-null
      Returns:
      non-null. If result code is RESULT_DEFERRED, callback will be called later
      Throws:
      I2PSessionException - if the router predates 0.9.11 and has no HostLookup
    • lookupDest

      LookupResult lookupDest(String name, 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.
      Parameters:
      name - the hostname to look up
      maxWait - milliseconds to wait for the router's reply before giving up
      callback - to return the result, non-null
      Returns:
      non-null. If result code is RESULT_DEFERRED, callback will be called later
      Throws:
      I2PSessionException - if the router predates 0.9.11 and has no HostLookup
    • updateOptions

      void updateOptions(Properties options)
      Pass updated options to the router. Does not remove properties previously present but missing from this options parameter. Fails silently if session is not connected.
      Parameters:
      options - non-null
    • bandwidthLimits

      int[] bandwidthLimits() throws I2PSessionException
      Current bandwidth limits; blocks until the response arrives.
      Returns:
      int array of [inbound, outbound] Bps, or null on error
      Throws:
      I2PSessionException - if the calling thread is interrupted while waiting
    • sendBlindingInfo

      void sendBlindingInfo(BlindData bd) throws I2PSessionException
      Send blinding info to the router.
      Parameters:
      bd - the blind data
      Throws:
      I2PSessionException - if the router predates 0.9.43 and has no BlindingInfo
    • getRouterVersion

      String getRouterVersion()
      Always valid in RouterContext. Returns null if not yet connected in I2PAppContext.
      Returns:
      null if unknown
    • addSessionListener

      void addSessionListener(I2PSessionListener lsnr, int proto, int port)
      Listen on specified protocol and port.

      An existing listener with the same proto and port is replaced. Only the listener with the best match is called back for each message.

      Parameters:
      lsnr - the listener to add
      proto - 1-254 or PROTO_ANY (0) for all; recommended: I2PSession.PROTO_STREAMING I2PSession.PROTO_DATAGRAM 255 disallowed
      port - 1-65535 or PORT_ANY (0) for all
    • addMuxedSessionListener

      void addMuxedSessionListener(I2PSessionMuxedListener l, int proto, int port)
      Listen on specified protocol and port, and receive notification of proto, fromPort, and toPort for every message.
      Parameters:
      l - the listener to add
      proto - 1-254 or PROTO_ANY (0) for all; 255 disallowed
      port - 1-65535 or PORT_ANY (0) for all
    • removeListener

      void removeListener(int proto, int port)
      Removes the specified listener (only).
      Parameters:
      proto - 1-254, or PROTO_ANY (0) to match any protocol
      port - 1-65535, or PORT_ANY (0) to match any port
    • addTunnelStatusListener

      void addTunnelStatusListener(TunnelStatusListener lsnr)
      Add a listener for tunnel status changes. This is used by the streaming library to react to tunnel failures and removals.
      Parameters:
      lsnr - the listener to add
    • removeTunnelStatusListener

      void removeTunnelStatusListener(TunnelStatusListener lsnr)
      Remove a tunnel status listener.
      Parameters:
      lsnr - the listener to remove
    • rebuildTunnels

      void rebuildTunnels()
      Force immediate tunnel rebuild. This triggers the tunnel pool to build new tunnels to replace failed ones. Useful when a connection fails and we want to ensure fresh tunnels before retry.
    • switchToNewTunnel

      boolean switchToNewTunnel()
      Switch to a new tunnel for this session. This forces the session to abandon its current tunnels and acquire fresh ones. Useful when connections are failing and we need to switch to better tunnels.
      Returns:
      true if switch was initiated successfully
    • getCurrentTunnelPair

      I2PSession.TunnelPair getCurrentTunnelPair()
      Get the tunnel IDs currently in use by this session. This allows the streaming library to track which tunnels are being used and react when those specific tunnels are removed.
      Returns:
      TunnelPair containing inbound and outbound tunnel IDs, or null if none
    • setCurrentTunnelPair

      void setCurrentTunnelPair(I2PSession.TunnelPair pair)
      Tunnel IDs actively in use by this session. Called by the streaming library when it learns which tunnels are being used.
      Parameters:
      pair - the tunnel pair in use