Class ClientConnectionRunner

java.lang.Object
net.i2p.router.client.ClientConnectionRunner
Direct Known Subclasses:
QueuedClientConnectionRunner

class ClientConnectionRunner extends Object
Bridge the router and the client - managing state for a client. As of release 0.9.21, multiple sessions are supported on a single I2CP connection. These sessions share tunnels and some configuration.
Author:
jrandom
  • Field Details

  • Constructor Details

    • ClientConnectionRunner

      public ClientConnectionRunner(RouterContext context, ClientManager manager, Socket socket)
      Create a new runner against the given socket
  • Method Details

    • startRunning

      public void startRunning() throws IOException
      Actually run the connection - listen for I2CP messages and respond. This is the main driver for this class, though it gets all its meat from the I2CPMessageReader
      Throws:
      IOException
    • createListener

      protected I2CPMessageReader.I2CPMessageEventListener createListener()
      Allow override for testing
      Since:
      0.9.8
    • stopRunning

      public void stopRunning()
      Die a horrible death. Cannot be restarted.
    • getConfig

      public SessionConfig getConfig(Hash h)
      Current client's config, will be null if session not found IS subsession aware.
      Since:
      0.9.21 added hash param
    • getConfig

      public SessionConfig getConfig(SessionId id)
      Current client's config, will be null if session not found IS subsession aware. Returns null if id is null.
      Since:
      0.9.21 added id param
    • getPrimaryConfig

      public SessionConfig getPrimaryConfig()
      Primary client's config, will be null if session not set up
      Since:
      0.9.21
    • setClientVersion

      public void setClientVersion(String version)
      The client version.
      Since:
      0.9.7
    • getClientVersion

      public String getClientVersion()
      The client version.
      Returns:
      null if unknown or less than 0.8.7
      Since:
      0.9.7
    • getSessionKeyManager

      public SessionKeyManager getSessionKeyManager()
      The current client's SessionKeyManager. As of 0.9.44, returned implementation varies based on supported encryption types.
    • getLeaseSet

      public LeaseSet getLeaseSet(Hash h)
      Currently allocated leaseSet. IS subsession aware. Returns primary leaseset only.
      Returns:
      leaseSet or null if not yet set or unknown hash
      Since:
      0.9.21 added hash parameter
    • getDestHash

      public Hash getDestHash()
      Equivalent to getConfig().getDestination().calculateHash(); will be null before session is established Not subsession aware. Returns primary session hash. Don't use if you can help it.
      Returns:
      primary hash or null if not yet set
    • getDestHash

      public Hash getDestHash(SessionId id)
      Return the hash for the given ID
      Returns:
      hash or null if unknown
      Since:
      0.9.21
    • getDestination

      public Destination getDestination(SessionId id)
      Return the dest for the given ID
      Returns:
      dest or null if unknown
      Since:
      0.9.21
    • getSessionId

      SessionId getSessionId(Hash h)
      Subsession aware.
      Parameters:
      h - the local target
      Returns:
      current client's sessionId or null if not yet set or not a valid hash
      Since:
      0.9.21
    • getSessionIds

      List<SessionId> getSessionIds()
      Subsession aware.
      Returns:
      all current client's sessionIds, non-null
      Since:
      0.9.21
    • getDestinations

      List<Destination> getDestinations()
      Subsession aware.
      Returns:
      all current client's destinations, non-null
      Since:
      0.9.21
    • setSessionId

      void setSessionId(Hash hash, SessionId id)
      To be called only by ClientManager.
      Parameters:
      hash - for the session
      Throws:
      IllegalStateException - if already set
      Since:
      0.9.21 added hash param
    • removeSession

      void removeSession(SessionId id)
      Kill the session. Caller must kill runner if none left.
      Since:
      0.9.21
    • getLeaseRequest

      LeaseRequestState getLeaseRequest(Hash h)
      Data for the current leaseRequest, or null if there is no active leaseSet request. Not subsession aware. Returns primary ID only.
      Since:
      0.9.21 added hash param
    • failLeaseRequest

      public void failLeaseRequest(LeaseRequestState req)
      Parameters:
      req - non-null
    • isDead

      boolean isDead()
      already closed?
    • getPayload

      Payload getPayload(MessageId id)
      Only call if _dontSendMSMOnReceive is false, otherwise will always be null
    • setPayload

      void setPayload(MessageId id, Payload payload)
      Only call if _dontSendMSMOnReceive is false
    • removePayload

      void removePayload(MessageId id)
      Only call if _dontSendMSMOnReceive is false
    • sessionEstablished

      public int sessionEstablished(SessionConfig config)
      Caller must send a SessionStatusMessage to the client with the returned code. Caller must call disconnectClient() on failure. Side effect: Sets the session ID.
      Returns:
      SessionStatusMessage return code, 1 for success, != 1 for failure
    • updateMessageDeliveryStatus

      void updateMessageDeliveryStatus(Destination dest, MessageId id, long messageNonce, int status)
      Send a notification to the client that their message (id specified) was delivered (or failed delivery) Note that this sends the Guaranteed status codes, even though we only support best effort. Doesn't do anything if i2cp.messageReliability = "none" Do not use for status = STATUS_SEND_ACCEPTED; use ackSendMessage() for that.
      Parameters:
      dest - the client
      id - the router's ID for this message
      messageNonce - the client's ID for this message, greater than zero
      status - see I2CP MessageStatusMessage for success/failure codes
    • leaseSetCreated

      void leaseSetCreated(LeaseSet ls)
      called after a new leaseSet is granted by the client, the NetworkDb has been updated. This takes care of all the LeaseRequestState stuff (including firing any jobs)
      Parameters:
      ls - if encrypted, the encrypted LS, not the decrypted one
    • registerEncryptedLS

      public boolean registerEncryptedLS(Hash hash)
      Call after destinationEstablished(), when an encrypted leaseset is created, so we know it's local. Add to the clients list. Check for a dup hash. Caller must call runner.disconnectClient() on failure.
      Parameters:
      hash - the location of the encrypted LS, will change every day
      Returns:
      success, false on dup
      Since:
      0.9.39
    • disconnectClient

      void disconnectClient(String reason)
      Send a DisconnectMessage and log with level Log.ERROR. This is always bad. See ClientMessageEventListener.handleCreateSession() for why we don't send a SessionStatusMessage when we do this.
      Parameters:
      reason - will be truncated to 255 bytes
    • disconnectClient

      void disconnectClient(String reason, int logLevel)
      Parameters:
      reason - will be truncated to 255 bytes
      logLevel - e.g. Log.WARN
      Since:
      0.8.2
    • distributeMessage

      MessageId distributeMessage(SendMessageMessage message)
      Distribute the message. If the dest is local, it blocks until its passed to the target ClientConnectionRunner (which then fires it into a MessageReceivedJob). If the dest is remote, it blocks until it is added into the ClientMessagePool
    • ackSendMessage

      void ackSendMessage(SessionId sid, MessageId id, long nonce)
      Send a notification to the client that their message (id specified) was accepted for delivery (but not necessarily delivered) Doesn't do anything if i2cp.messageReliability = "none" or if the nonce is 0.
      Parameters:
      id - OUR id for the message
      nonce - HIS id for the message
    • receiveMessage

      boolean receiveMessage(Destination toDest, Destination fromDest, Payload payload)
      Synchronously deliver the message to the current runner Failure indication is available as of 0.9.29. Fails on e.g. queue overflow to client, client dead, etc.
      Parameters:
      toDest - non-null
      fromDest - generally null when from remote, non-null if from local
      Returns:
      success
    • receiveMessage

      boolean receiveMessage(Hash toHash, Destination fromDest, Payload payload)
      Synchronously deliver the message to the current runner Failure indication is available as of 0.9.29. Fails on e.g. queue overflow to client, client dead, etc.
      Parameters:
      toHash - non-null
      fromDest - generally null when from remote, non-null if from local
      Returns:
      success
      Since:
      0.9.21
    • reportAbuse

      public void reportAbuse(Destination dest, String reason, int severity)
      Send async abuse message to the client
    • requestLeaseSet

      void requestLeaseSet(Hash h, LeaseSet set, long expirationTime, Job onCreateJob, Job onFailedJob)
      Request that a particular client authorize the Leases contained in the LeaseSet, after which the onCreateJob is queued up. If that doesn't occur within the timeout specified, queue up the onFailedJob. This call does not block. Job args are always null, may need some fixups if we start using them.
      Parameters:
      h - the Destination's hash
      set - LeaseSet with requested leases - this object must be updated to contain the signed version (as well as any changed/added/removed Leases) The LeaseSet contains Leases only, it is unsigned. Must be unique for this hash, do not reuse for subsessions.
      expirationTime - ms to wait before failing
      onCreateJob - Job to run after the LeaseSet is authorized, null OK
      onFailedJob - Job to run after the timeout passes without receiving authorization, null OK
    • disconnected

      void disconnected()
    • getIsDead

      boolean getIsDead()
    • writeMessage

      void writeMessage(I2CPMessage msg)
      Not thread-safe. Blocking. Only used for external sockets. ClientWriterRunner thread is the only caller. Others must use doSend().
    • doSend

      void doSend(I2CPMessage msg) throws I2CPMessageException
      Actually send the I2CPMessage to the peer through the socket
      Throws:
      I2CPMessageException
    • getNextMessageId

      public int getNextMessageId()