Class 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
    • Constructor Detail

      • ClientConnectionRunner

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

      • 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
      • 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().
      • getNextMessageId

        public int getNextMessageId()