java.lang.Object
net.i2p.client.impl.I2CPMessageProducer

class I2CPMessageProducerextends Object
Produce the various messages the session needs to send to the router.
  • Field Details

    • _log

      private final Log _log
      The log for the producer.
    • _context

      private final I2PAppContext _context
      The app context.
    • _maxBytesPerSecond

      private volatile int _maxBytesPerSecond
      The send rate limit, zero for none.
    • _sendPeriodBytes

      private volatile int _sendPeriodBytes
      Bytes allowed in the current send period.
    • _sendPeriodBeginTime

      private volatile long _sendPeriodBeginTime
      When the current send period began.
    • _lock

      private final ReentrantLock _lock
      The lock guarding the send state.
    • _throttleCondition

      private final Condition _throttleCondition
      Signalled when the send period refills.
    • PROP_MAX_BW

      private static final String PROP_MAX_BW
      Config key of the send rate limit.
      See Also:
    • TYP_SIZE

      private static final int TYP_SIZE
      See ConnectionOptions in streaming - MTU + streaming overhead + gzip overhead.
      See Also:
    • MIN_RATE

      private static final int MIN_RATE
      Smallest send rate limit allowed.
      See Also:
    • CLIENT_SIDE_OPTIONS

      private static final String[] CLIENT_SIDE_OPTIONS
      The I2CP options set by the client side, not the ones listed for both the client and the server side. See also: the I2CP protocol
  • Constructor Details

    • I2CPMessageProducer

      public I2CPMessageProducer(I2PAppContext context)
      Create a message producer for the given context.
      Parameters:
      context - the router context
  • Method Details

    • updateBandwidth

      public void updateBandwidth(I2PSessionImpl session)
      Update bandwidth limits from session options.
      Parameters:
      session - the session whose PROP_MAX_BW option supplies the new limit
    • getRouterOptions

      private Properties getRouterOptions(I2PSessionImpl session)
      Strip out the client-side options from the session options.
      Parameters:
      session - the session whose options are copied and filtered
      Returns:
      a new copy, may be modified
    • connect

      public void connect(I2PSessionImpl session) throws I2PSessionException
      Send all the messages that a client needs to send to a router to establish a new session.
      Parameters:
      session - the session to create the CreateSessionMessage for
      Throws:
      I2PSessionException - if the session's offline signature has expired, if the session config cannot be signed, or if the message cannot be queued
    • disconnect

      public void disconnect(I2PSessionImpl session) throws I2PSessionException
      Send a message to the router destroying the session, which could be a subsession. This does NOT close the socket.
      Parameters:
      session - the session or subsession to destroy, ignored if already closed
      Throws:
      I2PSessionException - if the message cannot be queued to the router
    • sendMessage

      public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SessionTag tag, SessionKey key, Set<SessionTag> tags, SessionKey newKey, long expires) throws I2PSessionException
      Package up and send the payload to the router for delivery.
      Parameters:
      session - the session to send the message on
      dest - the destination to deliver the message to
      nonce - 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage
      payload - the unencrypted message data
      tag - unused - no end-to-end crypto
      key - unused - no end-to-end crypto
      tags - unused - no end-to-end crypto
      newKey - unused - no end-to-end crypto
      expires - message expiration in milliseconds since the epoch, 0 for none
      Throws:
      I2PSessionException - if the payload is null or the message cannot be queued
    • sendMessage

      public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, long expires, int flags) throws I2PSessionException
      Package up and send the payload to the router for delivery.
      Parameters:
      session - the session to send the message on
      dest - the destination to deliver the message to
      nonce - 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage
      payload - the unencrypted message data
      expires - message expiration in milliseconds since the epoch, 0 for none
      flags - the raw flag bitmask to pass to the router, 0 for the defaults
      Throws:
      I2PSessionException - if the payload is null or the message cannot be queued
    • sendMessage

      public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SendMessageOptions options) throws I2PSessionException
      Package up and send the payload to the router for delivery.
      Parameters:
      session - the session to send the message on
      dest - the destination to deliver the message to
      nonce - 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage
      payload - the unencrypted message data
      options - the expiration, flags, tags and reliability to send with the message
      Throws:
      I2PSessionException - if the payload is null or the message cannot be queued
    • updateBps

      private boolean updateBps(int len, long expires)
      Super-simple bandwidth throttler. We only calculate on a one-second basis, so large messages (compared to the one-second limit) may exceed the limits. Tuned for streaming, may not work well for large datagrams.

      This does poorly with low rate limits since it doesn't credit bandwidth across two periods. So the limit is rounded up, and the min limit is set to 2x the typ size, above.

      Blocking so this could be very bad for retransmissions, as it could clog StreamingTimer. Waits are somewhat "fair" using ReentrantLock. While out-of-order transmission is acceptable, fairness reduces the chance of starvation. ReentrantLock does not guarantee in-order execution due to thread priority issues, so out-of-order may still occur. But shouldn't happen within the same thread anyway... Also note that small messages may go ahead of large ones that are waiting for the next window. Also, threads waiting a second time go to the back of the line.

      Since this is at the I2CP layer, it includes streaming overhead, streaming acks and retransmissions, gzip overhead (or "underhead" for compression), repliable datagram overhead, etc. However, it does not, of course, include the substantial overhead imposed by the router for the leaseset, tags, encryption, and fixed-size tunnel messages.

      Parameters:
      len - the size of the message in bytes, counted against the throttle
      expires - if $gt; 0, an expiration date
      Returns:
      true if we should send the message, false to drop it
    • createPayload

      private static Payload createPayload(byte[] payload) throws I2PSessionException
      Create a new payload. No more end-to-end encryption, just set the "encrypted" data to the payload.
      Parameters:
      payload - the message data, must not be null
      Returns:
      a Payload wrapping a copy of the supplied data, unencrypted
      Throws:
      I2PSessionException - if the payload is null
    • reportAbuse

      public void reportAbuse(I2PSessionImpl session, int msgId, int severity) throws I2PSessionException
      Send an abuse message to the router.
      Parameters:
      session - the session on whose behalf the abuse is reported
      msgId - the message ID the abuse refers to
      severity - the abuse severity level, larger numbers being more severe
      Throws:
      I2PSessionException - if the message cannot be queued to the router
    • createLeaseSet

      public void createLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv, List<PrivateKey> privs) throws I2PSessionException
      In response to a RequestLeaseSet Message from the router, send a CreateLeaseset Message back to the router. This method is misnamed, it does not create the LeaseSet, the caller does that.
      Parameters:
      session - the session on whose behalf the LeaseSet is created
      leaseSet - the LeaseSet to send, of type 0, 1 or 3
      signingPriv - unused for LS2 lease sets
      privs - the private keys to encrypt the LeaseSet with, the first entry being the signing key for type 0 and 1 LeaseSets
      Throws:
      I2PSessionException - if the session is closed
    • updateTunnels

      public void updateTunnels(I2PSessionImpl session, int tunnels) throws I2PSessionException
      Update number of tunnels.
      Parameters:
      session - the session to reconfigure
      tunnels - 0 for original configured number
      Throws:
      I2PSessionException - if the session configuration cannot be signed