Package net.i2p.client.impl
Class I2PSessionImpl
java.lang.Object
net.i2p.client.impl.I2PSessionImpl
- All Implemented Interfaces:
I2PSession
,I2CPMessageReader.I2CPMessageEventListener
- Direct Known Subclasses:
I2PSessionImpl2
public abstract class I2PSessionImpl extends Object implements I2PSession, I2CPMessageReader.I2CPMessageEventListener
Implementation of an I2P session running over TCP. This class is NOT thread safe -
only one thread should send messages at any given time
Public only for clearCache().
Except for methods defined in I2PSession and I2CPMessageEventListener,
not maintained as a public API, not for external use.
Use I2PClientFactory to get an I2PClient and then createSession().
- Author:
- jrandom
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected class
I2PSessionImpl.AvailabilityNotifier
This notifies the client of payload messages.protected static class
I2PSessionImpl.State
-
Field Summary
Fields Modifier and Type Field Description protected I2PSessionImpl.AvailabilityNotifier
_availabilityNotifier
thread that we tell when new messages are available who then tells us to fetch them.protected Map<Long,MessagePayloadMessage>
_availableMessages
map of Long --> MessagePayloadMessageprotected int[]
_bwLimits
protected Object
_bwReceivedLock
protected I2PAppContext
_context
used to separate things out so we can get rid of singletonsprotected I2PClientMessageHandlerMap
_handlerMap
protected String
_hostname
hostname of router - will be null if in RouterContextprotected LeaseSet
_leaseSet
currently granted lease set, or nullprotected Object
_leaseSetWait
monitor for waiting until a lease set has been grantedprotected Log
_log
protected LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter>
_pendingLookups
hashes of lookups we are waiting forprotected int
_portNum
port num to router - will be 0 if in RouterContextprotected I2CPMessageProducer
_producer
class that generates new messagesprotected I2CPMessageQueue
_queue
Used for internal connections to the router.protected I2CPMessageReader
_reader
reader that always searches for messagesprotected I2PSessionListener
_sessionListener
who we send events toprotected Socket
_socket
socket for commprotected I2PSessionImpl.State
_state
protected Object
_stateLock
protected SigningPublicKey
_transientSigningPublicKey
protected ClientWriterRunner
_writer
writer message queueprotected static int
CACHE_MAX_SIZE
static int
LISTEN_PORT
protected static String
PROP_DOMAIN_SOCKET
Use Unix domain socket (or similar) to connect to a routerFields inherited from interface net.i2p.client.I2PSession
PORT_ANY, PORT_UNSPECIFIED, PROTO_ANY, PROTO_DATAGRAM, PROTO_DATAGRAM_RAW, PROTO_STREAMING, PROTO_UNSPECIFIED
-
Constructor Summary
Constructors Modifier Constructor Description protected
I2PSessionImpl(I2PSessionImpl primary, InputStream destKeyStream, Properties options)
I2PSessionImpl(I2PAppContext context, InputStream destKeyStream, Properties options)
Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey from the destKeyStream, and using the specified options to connect to the router As of 0.9.19, defaults in options are honored.protected
I2PSessionImpl(I2PAppContext context, Properties options, I2PClientMessageHandlerMap handlerMap)
for extension by SimpleSession (no dest) -
Method Summary
Modifier and Type Method Description void
addNewMessage(MessagePayloadMessage msg)
Recieve a payload message and let the app know its availableI2PSession
addSubsession(InputStream privateKeyStream, Properties opts)
Router must be connected or was connected...int[]
bandwidthLimits()
Blocking.(package private) void
bwReceived(int[] i)
called by the message handlerprotected void
changeState(I2PSessionImpl.State state)
static void
clearCache()
void
connect()
Connect to the router and establish a session.(package private) void
dateUpdated(String routerVersion)
(package private) void
destLookupFailed(long nonce, int code)
Called by the message handler on reception of HostReplyMessage(package private) void
destLookupFailed(Hash h)
Called by the message handler on reception of DestReplyMessage(package private) void
destReceived(long nonce, Destination d)
Called by the message handler on reception of HostReplyMessage(package private) void
destReceived(Destination d)
Called by the message handler on reception of DestReplyMessagevoid
destroySession()
Tear down the session, and do NOT reconnect.void
destroySession(boolean sendDisconnect)
Tear down the session, and do NOT reconnect.protected void
disconnect()
Will interrupt a connect in progress.void
disconnected(I2CPMessageReader reader)
The I2CPMessageEventListener callback.(package private) I2PAppContext
getContext()
For SubsessionsPrivateKey
getDecryptionKey()
Retrieve the decryption PrivateKeyboolean
getFastReceive()
(package private) I2PClientMessageHandlerMap
getHandlerMap()
For Subsessions(package private) LeaseSet
getLeaseSet()
Destination
getMyDestination()
Retrieve the destination of the sessionprotected String
getName()
long
getOfflineExpiration()
Get the offline expirationSignature
getOfflineSignature()
(package private) Properties
getOptions()
Retrieve the configuration options, filtered.protected String
getPrefix()
try hard to make a decent identifier as this will appear in error logsSigningPrivateKey
getPrivateKey()
Retrieve the signing SigningPrivateKey.(package private) I2CPMessageProducer
getProducer()
Retrieve the helper that generates I2CP messagesString
getRouterVersion()
Always valid in RouterContext.(package private) SessionId
getSessionId()
Retrieve the session's IDList<I2PSession>
getSubsessions()
SigningPublicKey
getTransientSigningPublicKey()
boolean
isClosed()
Has the session been closed (or not yet connected)? False when open and during transitions.boolean
isOffline()
Does this session have offline and transient keys?long
lastActivity()
Destination
lookupDest(String name)
Ask the router to lookup a Destination by host name.Destination
lookupDest(String name, long maxWait)
Ask the router to lookup a Destination by host name.Destination
lookupDest(Hash h)
Blocking.Destination
lookupDest(Hash h, long maxWait)
Blocking.LookupResult
lookupDest2(String name, long maxWait)
Ask the router to lookup a Destination by host name.void
messageReceived(I2CPMessageReader reader, I2CPMessage message)
The I2CPMessageEventListener callback.(package private) void
propogateError(String msg, Throwable error)
Pass off the error to the listener Misspelled, oh well.void
readError(I2CPMessageReader reader, Exception error)
The I2CPMessageEventListener callback.byte[]
receiveMessage(int msgId)
Pull the unencrypted data from the message that we've already prefetched and notified the user that its available.abstract void
receiveStatus(int msgId, long nonce, int status)
protected boolean
reconnect()
void
removeSubsession(I2PSession session)
void
reportAbuse(int msgId, int severity)
Report abuse with regards to the given messageIdvoid
sendBlindingInfo(BlindData bd)
(package private) void
sendMessage(I2CPMessage message)
Deliver an I2CP message to the router As of 0.9.3, may block for several seconds if the write queue to the router is full(package private) void
sendMessage_unchecked(I2CPMessage message)
Deliver an I2CP message to the router.(package private) void
setLeaseSet(LeaseSet ls)
void
setReduced()
(package private) void
setSessionId(SessionId id)
void
setSessionListener(I2PSessionListener lsnr)
configure the listenerprotected boolean
shouldReconnect()
protected void
startVerifyUsage()
Fire up a periodic task to check for unclaimed messagesboolean
supportsLS2()
String
toString()
protected void
updateActivity()
void
updateOptions(Properties options)
Update the tunnel and bandwidth settingsprotected void
verifyOpen()
Throws I2PSessionException if uninitialized, closed or closing.protected void
waitForDate()
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Methods inherited from interface net.i2p.client.I2PSession
addMuxedSessionListener, addSessionListener, removeListener, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage, sendMessage
-
Field Details
-
_log
-
_leaseSet
currently granted lease set, or null -
_transientSigningPublicKey
-
_hostname
hostname of router - will be null if in RouterContext -
_portNum
protected final int _portNumport num to router - will be 0 if in RouterContext -
_socket
socket for comm -
_reader
reader that always searches for messages -
_writer
writer message queue -
_queue
Used for internal connections to the router. If this is set, _socket and _writer will be null.- Since:
- 0.8.3
-
_sessionListener
who we send events to -
_producer
class that generates new messages -
_availableMessages
map of Long --> MessagePayloadMessage -
_pendingLookups
protected final LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter> _pendingLookupshashes of lookups we are waiting for -
_bwReceivedLock
-
_bwLimits
protected volatile int[] _bwLimits -
_handlerMap
-
_context
used to separate things out so we can get rid of singletons -
_leaseSetWait
monitor for waiting until a lease set has been granted -
_state
-
_stateLock
-
_availabilityNotifier
thread that we tell when new messages are available who then tells us to fetch them. The point of this is so that the fetch doesn't block the reading of other messages (in turn, potentially leading to deadlock) -
CACHE_MAX_SIZE
protected static final int CACHE_MAX_SIZE -
PROP_DOMAIN_SOCKET
Use Unix domain socket (or similar) to connect to a router- Since:
- 0.9.14
- See Also:
- Constant Field Values
-
LISTEN_PORT
public static final int LISTEN_PORT- See Also:
- Constant Field Values
-
-
Constructor Details
-
I2PSessionImpl
protected I2PSessionImpl(I2PAppContext context, Properties options, I2PClientMessageHandlerMap handlerMap)for extension by SimpleSession (no dest) -
I2PSessionImpl
protected I2PSessionImpl(I2PSessionImpl primary, InputStream destKeyStream, Properties options) throws I2PSessionException- Throws:
I2PSessionException
-
I2PSessionImpl
public I2PSessionImpl(I2PAppContext context, InputStream destKeyStream, Properties options) throws I2PSessionExceptionCreate a new session, reading the Destination, PrivateKey, and SigningPrivateKey from the destKeyStream, and using the specified options to connect to the router As of 0.9.19, defaults in options are honored. This does NOT validate consistency of the destKeyStream, e.g. pubkey/privkey match or valid offline sig. The router does that.- Parameters:
destKeyStream
- stream containing the private key data, format is specified inPrivateKeyFile
options
- set of options to configure the router with, if null will use System properties- Throws:
I2PSessionException
- if there is a problem loading the private keys
-
-
Method Details
-
dateUpdated
- Parameters:
routerVersion
- as rcvd in the SetDateMessage, may be null for very old routers
-
addSubsession
public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionExceptionRouter must be connected or was connected... for now.- Specified by:
addSubsession
in interfaceI2PSession
- Parameters:
privateKeyStream
- null for transient, if non-null must have same encryption keys as primary session and different signing keysopts
- subsession options if any, may be null- Returns:
- a new subsession, non-null
- Throws:
I2PSessionException
- Since:
- 0.9.21
-
removeSubsession
- Specified by:
removeSubsession
in interfaceI2PSession
- Since:
- 0.9.21
-
getSubsessions
- Specified by:
getSubsessions
in interfaceI2PSession
- Returns:
- a list of subsessions, non-null, does not include the primary session
- Since:
- 0.9.21
-
updateOptions
Update the tunnel and bandwidth settings- Specified by:
updateOptions
in interfaceI2PSession
- Parameters:
options
- non-null- Since:
- 0.8.4
-
getFastReceive
public boolean getFastReceive()- Since:
- 0.9.4
-
supportsLS2
public boolean supportsLS2()- Since:
- 0.9.38
-
setLeaseSet
-
getLeaseSet
LeaseSet getLeaseSet() -
changeState
-
isOffline
public boolean isOffline()Does this session have offline and transient keys?- Specified by:
isOffline
in interfaceI2PSession
- Since:
- 0.9.38
-
getOfflineExpiration
public long getOfflineExpiration()Description copied from interface:I2PSession
Get the offline expiration- Specified by:
getOfflineExpiration
in interfaceI2PSession
- Returns:
- Java time (ms) or 0 if not initialized or does not have offline keys
- Since:
- 0.9.38
-
getOfflineSignature
- Specified by:
getOfflineSignature
in interfaceI2PSession
- Returns:
- null on error or if not initialized or does not have offline keys
- Since:
- 0.9.38
-
getTransientSigningPublicKey
- Specified by:
getTransientSigningPublicKey
in interfaceI2PSession
- Returns:
- null on error or if not initialized or does not have offline keys
- Since:
- 0.9.38
-
connect
Connect to the router and establish a session. This call blocks until a session is granted. Should be threadsafe, other threads will block until complete. Disconnect / destroy from another thread may be called simultaneously and will (should?) interrupt the connect. Connecting a primary session will not automatically connect subsessions. Connecting a subsession will automatically connect the primary session if not previously connected.- Specified by:
connect
in interfaceI2PSession
- Throws:
I2PSessionException
- if there is a configuration error or the router is not reachable
-
waitForDate
- Throws:
InterruptedException
IOException
- Since:
- 0.9.11 moved from connect()
-
receiveMessage
Pull the unencrypted data from the message that we've already prefetched and notified the user that its available.- Specified by:
receiveMessage
in interfaceI2PSession
- Parameters:
msgId
- message to fetch- Returns:
- unencrypted body of the message, or null if not found
- Throws:
I2PSessionException
-
reportAbuse
Report abuse with regards to the given messageId- Specified by:
reportAbuse
in interfaceI2PSession
- Parameters:
msgId
- message that was abusive (or -1 for not message related)severity
- how abusive- Throws:
I2PSessionException
-
receiveStatus
public abstract void receiveStatus(int msgId, long nonce, int status) -
addNewMessage
Recieve a payload message and let the app know its available -
startVerifyUsage
protected void startVerifyUsage()Fire up a periodic task to check for unclaimed messages- Since:
- 0.9.1
-
messageReceived
The I2CPMessageEventListener callback. Recieve notification of some I2CP message and handle it if possible. We route the message based on message type AND session ID. The following types never contain a session ID and are not routable to a subsession: BandwidthLimitsMessage, DestReplyMessage The following types may not contain a valid session ID even when intended for a subsession, so we must take special care: SessionStatusMessage- Specified by:
messageReceived
in interfaceI2CPMessageReader.I2CPMessageEventListener
- Parameters:
reader
- unusedmessage
- the I2CPMessage
-
readError
The I2CPMessageEventListener callback. Recieve notifiation of an error reading the I2CP stream. As of 0.9.41, does NOT call sessionlistener.disconnected(), the I2CPMessageReader will call disconnected() also.- Specified by:
readError
in interfaceI2CPMessageReader.I2CPMessageEventListener
- Parameters:
reader
- unusederror
- non-null
-
getMyDestination
Retrieve the destination of the session- Specified by:
getMyDestination
in interfaceI2PSession
-
getDecryptionKey
Retrieve the decryption PrivateKey- Specified by:
getDecryptionKey
in interfaceI2PSession
-
getPrivateKey
Retrieve the signing SigningPrivateKey. As of 0.9.38, this will be the transient key if offline signed.- Specified by:
getPrivateKey
in interfaceI2PSession
-
getProducer
I2CPMessageProducer getProducer()Retrieve the helper that generates I2CP messages -
getHandlerMap
I2PClientMessageHandlerMap getHandlerMap()For Subsessions- Since:
- 0.9.21
-
getContext
I2PAppContext getContext()For Subsessions- Since:
- 0.9.21
-
getOptions
Properties getOptions()Retrieve the configuration options, filtered. All defaults passed in via constructor have been promoted to the primary map.- Returns:
- non-null, if instantiated with null options, this will be the System properties.
-
getSessionId
SessionId getSessionId()Retrieve the session's ID -
setSessionId
-
setSessionListener
configure the listener- Specified by:
setSessionListener
in interfaceI2PSession
- Parameters:
lsnr
- listener to retrieve events
-
isClosed
public boolean isClosed()Has the session been closed (or not yet connected)? False when open and during transitions. Synchronized.- Specified by:
isClosed
in interfaceI2PSession
- Returns:
- true if the session is closed, OR connect() has not been called yet
-
verifyOpen
Throws I2PSessionException if uninitialized, closed or closing. Blocks if opening.- Throws:
I2PSessionException
- Since:
- 0.9.23
-
sendMessage
Deliver an I2CP message to the router As of 0.9.3, may block for several seconds if the write queue to the router is full- Throws:
I2PSessionException
- if the message is malformed or there is an error writing it out
-
sendMessage_unchecked
Deliver an I2CP message to the router. Does NOT check state. Call only from connect() or other methods that need to send messages when not in OPEN state.- Throws:
I2PSessionException
- if the message is malformed or there is an error writing it out- Since:
- 0.9.23
-
propogateError
Pass off the error to the listener Misspelled, oh well. Calls sessionlistener.errorOccurred()- Parameters:
error
- non-null
-
destroySession
public void destroySession()Tear down the session, and do NOT reconnect. Blocks if session has not been fully started.- Specified by:
destroySession
in interfaceI2PSession
-
destroySession
public void destroySession(boolean sendDisconnect)Tear down the session, and do NOT reconnect. Will interrupt an open in progress. Calls sessionlistener.disconnected() -
disconnected
The I2CPMessageEventListener callback. Recieve notification that the I2CP connection was disconnected. Calls sessionlistener.disconnected()- Specified by:
disconnected
in interfaceI2CPMessageReader.I2CPMessageEventListener
- Parameters:
reader
- unused
-
disconnect
protected void disconnect()Will interrupt a connect in progress. Calls sessionlistener.disconnected() -
shouldReconnect
protected boolean shouldReconnect() -
reconnect
protected boolean reconnect() -
getPrefix
try hard to make a decent identifier as this will appear in error logs -
getName
- Since:
- 0.9.46
-
destReceived
Called by the message handler on reception of DestReplyMessage- Parameters:
d
- non-null
-
destLookupFailed
Called by the message handler on reception of DestReplyMessage- Parameters:
h
- non-null
-
destReceived
Called by the message handler on reception of HostReplyMessage- Parameters:
d
- non-null- Since:
- 0.9.11
-
destLookupFailed
void destLookupFailed(long nonce, int code)Called by the message handler on reception of HostReplyMessage- Since:
- 0.9.11
-
bwReceived
void bwReceived(int[] i)called by the message handler -
clearCache
public static void clearCache()- Since:
- 0.9.20
-
lookupDest
Blocking. Waits a max of 10 seconds by default. See lookupDest with maxWait parameter to change. Implemented in 0.8.3 in I2PSessionImpl; previously was available only in I2PSimpleSession. Multiple outstanding lookups are now allowed.- Specified by:
lookupDest
in interfaceI2PSession
- Returns:
- null on failure
- Throws:
I2PSessionException
-
lookupDest
Blocking.- Specified by:
lookupDest
in interfaceI2PSession
- Parameters:
maxWait
- ms- Returns:
- null on failure
- Throws:
I2PSessionException
- Since:
- 0.8.3
-
lookupDest
Ask the router to lookup a Destination by host name. Blocking. Waits a max of 10 seconds by default. This only makes sense for a b32 hostname, OR outside router context. Inside router context, just query the naming service. Outside router context, this does NOT query the context naming service. Do that first if you expect a local addressbook. This will log a warning for non-b32 in router context. See interface for suggested implementation. Requires router side to be 0.9.11 or higher. If the router is older, this will return null immediately.- Specified by:
lookupDest
in interfaceI2PSession
- Throws:
I2PSessionException
- Since:
- 0.9.11
-
lookupDest
Ask the router to lookup a Destination by host name. Blocking. See above for details.- Specified by:
lookupDest
in interfaceI2PSession
- Parameters:
maxWait
- ms- Returns:
- null on failure
- Throws:
I2PSessionException
- Since:
- 0.9.11
-
lookupDest2
Ask the router to lookup a Destination by host name. Blocking. See above for details. Same as lookupDest() but with a failure code in the return value- Specified by:
lookupDest2
in interfaceI2PSession
- Parameters:
maxWait
- ms- Returns:
- non-null
- Throws:
I2PSessionException
- Since:
- 0.9.43
-
bandwidthLimits
Blocking. Waits a max of 5 seconds. But shouldn't take long. Implemented in 0.8.3 in I2PSessionImpl; previously was available only in I2PSimpleSession. Multiple outstanding lookups are now allowed.- Specified by:
bandwidthLimits
in interfaceI2PSession
- Returns:
- null on failure
- Throws:
I2PSessionException
-
sendBlindingInfo
- Specified by:
sendBlindingInfo
in interfaceI2PSession
- Throws:
I2PSessionException
- Since:
- 0.9.43
-
getRouterVersion
Always valid in RouterContext. Returns null if not yet connected in I2PAppContext.- Specified by:
getRouterVersion
in interfaceI2PSession
- Returns:
- null if unknown
- Since:
- 0.9.46
-
updateActivity
protected void updateActivity() -
lastActivity
public long lastActivity() -
setReduced
public void setReduced() -
toString
-