## net.i2p.crypto
Class TransientSessionKeyManager

    java.lang.Object
      net.i2p.crypto.SessionKeyManager
          net.i2p.crypto.TransientSessionKeyManager

    public class TransientSessionKeyManager

extends SessionKeyManager

Implement the session key management, but keep everything in memory (don't write to disk). However, this being java, we cannot guarantee that the keys aren't swapped out to disk so this should not be considered secure in that sense. The outbound and inbound sides are completely independent, each with their own keys and tags. For a new session, outbound tags are not considered delivered until an ack is received. Otherwise, the loss of the first message would render all subsequent messages undecryptable. True? For an existing session, outbound tags are immediately considered delivered, and are later revoked if the ack times out. This prevents massive stream slowdown caused by repeated tag delivery after the minimum tag threshold is reached. Included tags pushes messages above the ideal 1956 size by ~2KB and causes excessive fragmentation and padding. As the tags are not seen by the streaming lib, they aren't accounted for in the window size, and one or more of a series of large messages is likely to be dropped, either due to high fragmentation or drop priorites at the tunnel OBEP. For this to work, the minimum tag threshold and tag delivery quanitity defined in GarlicMessageBuilder must be chosen with streaming lib windows sizes in mind. If a single TagSet is not delivered, there will be no stall as long as the current window size is smaller than the minimum tag threshold. Additional TagSets will be sent before the acked tags completely run out. See below. all subsequent messages will fail to decrypt. See ConnectionOptions in streaming for more information. There are large inefficiencies caused by the repeated delivery of tags in a new session. With an initial streaming window size of 6 and 40 tags per delivery, a web server would deliver up to 240 tags (7680 bytes, not including bundled leaseset, etc.) in the first volley of the response. Could the two directions be linked somehow, such that the initial request could contain a key or tags for the response? Should the tag threshold and quantity be adaptive? Todo: Switch to ConcurrentHashMaps and ReadWriteLocks, only get write lock during cleanup

Field Summary
`protected I2PAppContext` `_context`
`static int` `MAX_INBOUND_SESSION_TAGS` a few MB? how about 16MB! This is the max size of _inboundTagSets.
`static long` `SESSION_LIFETIME_MAX_MS` Keep unused inbound session tags around for up to 12 minutes (2 minutes longer than session tags are used on the outbound side so that no reasonable network lag can cause failed decrypts)
`static long` `SESSION_TAG_DURATION_MS` Let session tags sit around for 10 minutes before expiring them.

Constructor Summary
`TransientSessionKeyManager(I2PAppContext context)` The session key manager should only be constructed and accessed through the application context.

Method Summary
`SessionTag` `consumeNextAvailableTag(PublicKey target, SessionKey key)` Retrieve the next available session tag for identifying the use of the given key when communicating with the target.
`SessionKey` `consumeTag(SessionTag tag)` Determine if we have received a session key associated with the given session tag, and if so, discard it (but keep track for frequent dups) and return the decryption key it was received with (via tagsReceived(...)).
`void` `createSession(PublicKey target, SessionKey key)` Associate a new session key with the specified target.
`void` `failTags(PublicKey target)` Deprecated. unused and rather drastic
`void` `failTags(PublicKey target, SessionKey key, TagSetHandle ts)` Mark these tags as invalid, since the peer has failed to ack them in time.
`int` `getAvailableTags(PublicKey target, SessionKey key)` Determine (approximately) how many available session tags for the current target have been confirmed and are available
`long` `getAvailableTimeLeft(PublicKey target, SessionKey key)` Determine how long the available tags will be available for before expiring, in milliseconds
`SessionKey` `getCurrentKey(PublicKey target)` Retrieve the session key currently associated with encryption to the target, or null if a new session key should be generated.
`void` `renderStatusHTML(Writer out)`
`void` `shutdown()` Called when the system is closing down, instructing the session key manager to take whatever precautions are necessary (saving state, etc)
`void` `tagsAcked(PublicKey target, SessionKey key, TagSetHandle ts)` Mark these tags as acked, start to use them (if we haven't already)
`TagSetHandle` `tagsDelivered(PublicKey target, SessionKey key, Set<SessionTag> sessionTags)` Take note of the fact that the given sessionTags associated with the key for encryption to the target have been sent.
`void` `tagsReceived(SessionKey key, Set<SessionTag> sessionTags)` Accept the given tags and associate them with the given key for decryption

Methods inherited from class net.i2p.crypto.SessionKeyManager
`createSession`

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

Field Detail

### _context

    protected I2PAppContext _context

### SESSION_TAG_DURATION_MS

    public static final long SESSION_TAG_DURATION_MS

  Let session tags sit around for 10 minutes before expiring them. We can now have such a large value since there is the persistent session key manager. This value is for outbound tags - inbound tags are managed by SESSION_LIFETIME_MAX_MS

  See Also:
    Constant Field Values

### SESSION_LIFETIME_MAX_MS

    public static final long SESSION_LIFETIME_MAX_MS

  Keep unused inbound session tags around for up to 12 minutes (2 minutes longer than session tags are used on the outbound side so that no reasonable network lag can cause failed decrypts)

  See Also:
    Constant Field Values

### MAX_INBOUND_SESSION_TAGS

    public static final int MAX_INBOUND_SESSION_TAGS

  a few MB? how about 16MB! This is the max size of _inboundTagSets.

  See Also:
    Constant Field Values

Constructor Detail

### TransientSessionKeyManager

    public TransientSessionKeyManager(I2PAppContext context)

  The session key manager should only be constructed and accessed through the application context. This constructor should only be used by the appropriate application context itself.

Method Detail

### shutdown

    public void shutdown()

  Description copied from class: `SessionKeyManager`
  Called when the system is closing down, instructing the session key manager to take whatever precautions are necessary (saving state, etc)

  Overrides:
    `shutdown` in class `SessionKeyManager`

### getCurrentKey

    public SessionKey getCurrentKey(PublicKey target)

  Retrieve the session key currently associated with encryption to the target, or null if a new session key should be generated.

  Overrides:
    `getCurrentKey` in class `SessionKeyManager`

### createSession

    public void createSession(PublicKey target,
                              SessionKey key)

  Associate a new session key with the specified target. Metrics to determine when to expire that key begin with this call.

  Overrides:
    `createSession` in class `SessionKeyManager`

### consumeNextAvailableTag

    public SessionTag consumeNextAvailableTag(PublicKey target,
                                              SessionKey key)

  Retrieve the next available session tag for identifying the use of the given key when communicating with the target. If this returns null, no tags are available so ElG should be used with the given key (a new sessionKey should NOT be used)

  Overrides:
    `consumeNextAvailableTag` in class `SessionKeyManager`

### getAvailableTags

    public int getAvailableTags(PublicKey target,
                                SessionKey key)

  Determine (approximately) how many available session tags for the current target have been confirmed and are available

  Overrides:
    `getAvailableTags` in class `SessionKeyManager`

### getAvailableTimeLeft

    public long getAvailableTimeLeft(PublicKey target,
                                     SessionKey key)

  Determine how long the available tags will be available for before expiring, in milliseconds

  Overrides:
    `getAvailableTimeLeft` in class `SessionKeyManager`

### tagsDelivered

    public TagSetHandle tagsDelivered(PublicKey target,
                                      SessionKey key,
                                      Set<SessionTag> sessionTags)

  Take note of the fact that the given sessionTags associated with the key for encryption to the target have been sent. Whether to use the tags immediately (i.e. assume they will be received) or to wait until an ack, is implementation dependent. Here, we wait for the ack if the session is new, otherwise we use right away. Will this work??? If the tags are pipelined sufficiently, it will.

  Overrides:
    `tagsDelivered` in class `SessionKeyManager`
  Returns:
    the TagSetHandle. Caller MUST subsequently call failTags() or tagsAcked() with this handle.

### failTags

    public void failTags(PublicKey target)

  Deprecated. unused and rather drastic

  Mark all of the tags delivered to the target up to this point as invalid, since the peer has failed to respond when they should have. This call essentially lets the system recover from corrupted tag sets and crashes

  Overrides:
    `failTags` in class `SessionKeyManager`

### failTags

    public void failTags(PublicKey target,
                         SessionKey key,
                         TagSetHandle ts)

  Mark these tags as invalid, since the peer has failed to ack them in time.

  Overrides:
    `failTags` in class `SessionKeyManager`

### tagsAcked

    public void tagsAcked(PublicKey target,
                          SessionKey key,
                          TagSetHandle ts)

  Mark these tags as acked, start to use them (if we haven't already)

  Overrides:
    `tagsAcked` in class `SessionKeyManager`

### tagsReceived

    public void tagsReceived(SessionKey key,
                             Set<SessionTag> sessionTags)

  Accept the given tags and associate them with the given key for decryption

  Overrides:
    `tagsReceived` in class `SessionKeyManager`

### consumeTag

    public SessionKey consumeTag(SessionTag tag)

  Determine if we have received a session key associated with the given session tag, and if so, discard it (but keep track for frequent dups) and return the decryption key it was received with (via tagsReceived(...)). returns null if no session key matches

  Overrides:
    `consumeTag` in class `SessionKeyManager`

### renderStatusHTML

    public void renderStatusHTML(Writer out)
                          throws IOException

  Overrides:
    `renderStatusHTML` in class `SessionKeyManager`
  Throws:
    `IOException`