java.lang.Object
net.i2p.router.client.ClientMessageEventListener
All Implemented Interfaces:
I2CPMessageReader.I2CPMessageEventListener

class ClientMessageEventListenerextends Object implements I2CPMessageReader.I2CPMessageEventListener
Receive events from the client and handle them accordingly (updating the runner when necessary).
  • Field Details

    • _log

      private final Log _log
      Logger for this class.
    • _context

      protected final RouterContext _context
      The router context.
    • _runner

      protected final ClientConnectionRunner _runner
      The client connection runner.
    • _enforceAuth

      private final boolean _enforceAuth
      True when the client must present credentials.
    • _authorized

      private volatile boolean _authorized
      True once the client has authenticated.
    • PROP_AUTH

      private static final String PROP_AUTH
      Property naming the client's credentials.
      See Also:
    • PROP_AUTH_STRICT

      private static final String PROP_AUTH_STRICT
      If true, user/pw must be in GetDateMessage.
      See Also:
  • Constructor Details

    • ClientMessageEventListener

      public ClientMessageEventListener(RouterContext context, ClientConnectionRunner runner, boolean enforceAuth)
      Create a new event listener for the given client connection.
      Parameters:
      context - the router context
      runner - the client connection runner
      enforceAuth - set false for in-JVM, true for socket access
  • Method Details

    • messageReceived

      public void messageReceived(I2CPMessageReader reader, I2CPMessage message)
      Handle an incoming message and dispatch it to the appropriate handler.
      Specified by:
      messageReceived in interface I2CPMessageReader.I2CPMessageEventListener
      Parameters:
      reader - I2CPMessageReader to notify
      message - the I2CPMessage
    • readError

      public void readError(I2CPMessageReader reader, Exception error)
      Handle notification that there was an error.
      Specified by:
      readError in interface I2CPMessageReader.I2CPMessageEventListener
      Parameters:
      reader - I2CPMessageReader to notify
      error - Exception that was thrown, non-null
    • disconnected

      public void disconnected(I2CPMessageReader reader)
      Description copied from interface: I2CPMessageReader.I2CPMessageEventListener
      Notify the listener that the stream this reader was reading was closed. For most errors, I2CPMessageReader.I2CPMessageEventListener.readError(I2CPMessageReader, Exception) will be called first, as of 0.9.41.
      Specified by:
      disconnected in interface I2CPMessageReader.I2CPMessageEventListener
      Parameters:
      reader - I2CPMessageReader to notify
    • handleGetDate

      private void handleGetDate(GetDateMessage message)
      Defaults in GetDateMessage options are NOT honored. Defaults are not serialized out-of-JVM, and the router does not recognize defaults in-JVM. Client side must promote defaults to the primary map.
      Parameters:
      message - the client's date request carrying its version and options
    • handleSetDate

      private void handleSetDate(SetDateMessage message)
      Do not allow a client to set the router's clock. As of 0.8.7 this handler deliberately does nothing.
      Parameters:
      message - the client's date request, ignored
    • handleCreateSession

      private void handleCreateSession(CreateSessionMessage message)
      Handle a CreateSessionMessage. On errors, we could perhaps send a SessionStatusMessage with STATUS_INVALID before sending the DisconnectMessage... but right now the client will send _us_ a DisconnectMessage in return, and not wait around for our DisconnectMessage. So keep it simple.

      Defaults in SessionConfig options are, in general, NOT honored. In-JVM client side must promote defaults to the primary map.

      Parameters:
      message - the session creation request carrying the SessionConfig
    • checkAuth

      private boolean checkAuth(Properties props)
      Side effect - sets _authorized. Side effect - disconnects session if not authorized.
      Parameters:
      props - contains i2cp.username and i2cp.password, may be null
      Returns:
      true if the session is authorized; false if authentication is enforced and failed, which disconnects the client
    • startCreateSessionJob

      protected void startCreateSessionJob(SessionConfig config)
      Override for testing.
      Parameters:
      config - the session config
    • handleSendMessage

      private void handleSendMessage(SendMessageMessage message)
      Handle a SendMessageMessage: give it a message Id, have the ClientManager distribute it, and send the client an ACCEPTED message.
      Parameters:
      message - the outbound message with its session id and payload
    • classifyReceiveBegin

      static ClientMessageEventListener.ReceiveRequest classifyReceiveBegin(SessionConfig cfg, Payload payload)
      Validate a ReceiveMessageBeginMessage before any retained payload is read.

      The router keeps a single payload map per connection, not per session, so a message that names a message id alone is not enough to authorize access. The message must also name a live session on this connection. Session-level validation is the right granularity because every session on a connection must already share one keypair, so sessions of one connection are not mutually untrusted.

      Parameters:
      cfg - the session named by the message, or null if there is no such session
      payload - the retained payload for the message id, or null if none is retained
      Returns:
      the request outcome, never null
    • classifyReceiveEnd

      static ClientMessageEventListener.ReceiveRequest classifyReceiveEnd(SessionConfig cfg, Payload payload)
      Validate a ReceiveMessageEndMessage before the retained payload is released.

      Uses the same rule as classifyReceiveBegin(SessionConfig, Payload): the message must name a live session on this connection, and the payload must actually be retained. A message id that is not retained needs no action, so it is reported separately from a rejected session.

      Parameters:
      cfg - the session named by the message, or null if there is no such session
      payload - the retained payload for the message id, or null if none is retained
      Returns:
      the request outcome, never null
    • handleReceiveBegin

      private void handleReceiveBegin(ReceiveMessageBeginMessage message)
      The client asked for a message, so we send it to them.

      This is only when not in fast receive mode. In the default fast receive mode, data is sent in MessageReceivedJob.

      A message naming no live session is dropped, as is a message for which no payload is retained; see classifyReceiveBegin(SessionConfig, Payload).

      Parameters:
      message - the request naming the message id to deliver
    • handleReceiveEnd

      private void handleReceiveEnd(ReceiveMessageEndMessage message)
      The client told us that the message has been received completely, so the retained payload is released.

      The message must name a live session on this connection. The payload map is per connection rather than per session, so a message id alone would otherwise let a client release a payload it was never sent.

      Parameters:
      message - the confirmation naming the fully received message id
    • handleDestroySession

      private void handleDestroySession(DestroySessionMessage message)
      Tears down the session the client asked to destroy.
      Parameters:
      message - the request to act on
    • handleCreateLeaseSet

      protected void handleCreateLeaseSet(CreateLeaseSetMessage message)
      Handle a CreateLeaseSet message. Override for testing.
      Parameters:
      message - the client request supplying the LeaseSet, its signing keys, and the session it applies to
    • handleDestLookup

      protected void handleDestLookup(DestLookupMessage message)
      Handle a DestLookup message. Override for testing.
      Parameters:
      message - the request naming the RouterInfo hash to resolve
    • handleHostLookup

      protected void handleHostLookup(HostLookupMessage message)
      Handle a HostLookup message. Override for testing.
      Parameters:
      message - the lookup request supplying the session and request ID
    • handleReconfigureSession

      private void handleReconfigureSession(ReconfigureSessionMessage message)
      Message's Session ID ignored. This doesn't support removing previously set options. Nor do we bother with message.getSessionConfig().verifySignature() ... should we? Nor is the Date checked.

      Note that this does NOT update the few options handled in ClientConnectionRunner.sessionEstablished(SessionConfig). Those can't be changed later.

      Defaults in SessionConfig options are, in general, NOT honored. In-JVM client side must promote defaults to the primary map.

      Parameters:
      message - the reconfiguration request with the session id and new config
    • sendStatusMessage

      private void sendStatusMessage(SessionId id, int status)
      Sends a status report to the client.
      Parameters:
      id - the session the status is about
      status - the status code to send
    • handleGetBWLimits

      protected void handleGetBWLimits(GetBandwidthLimitsMessage message)
      Divide router limit by 1.5 for overhead. This could someday give a different answer to each client. But it's not enforced anywhere.

      protected for unit test override.

      Parameters:
      message - the client's bandwidth query, which carries no data
    • handleBlindingInfo

      private void handleBlindingInfo(BlindingInfoMessage message)
      Handle blinded-lookup info from a peer.
      Parameters:
      message - the blinding data sent by the client