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 ClassesModifier and TypeClassDescriptionprotected classThis notifies the client of payload messages.protected static enum -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected I2PSessionImpl.AvailabilityNotifierthread that we tell when new messages are available who then tells us to fetch them.protected Map<Long,MessagePayloadMessage> map of Long --> MessagePayloadMessageprotected int[]protected final Objectprotected final I2PAppContextused to separate things out so we can get rid of singletonsprotected final I2PClientMessageHandlerMapprotected final Stringhostname of router - will be null if in RouterContextprotected LeaseSetcurrently granted lease set, or nullprotected final Objectmonitor for waiting until a lease set has been grantedprotected final Logprotected final LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter>hashes of lookups we are waiting forprotected final intport num to router - will be 0 if in RouterContextprotected final I2CPMessageProducerclass that generates new messagesprotected I2CPMessageQueueUsed for internal connections to the router.protected I2CPMessageReaderreader that always searches for messagesprotected I2PSessionListenerwho we send events toprotected Socketsocket for commprotected I2PSessionImpl.Stateprotected final Objectprotected SigningPublicKeyprotected ClientWriterRunnerwriter message queueprotected static final intstatic final intprotected static final StringUse 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
ConstructorsModifierConstructorDescriptionprotectedI2PSessionImpl(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.protectedI2PSessionImpl(I2PAppContext context, Properties options, I2PClientMessageHandlerMap handlerMap) for extension by SimpleSession (no dest) -
Method Summary
Modifier and TypeMethodDescriptionvoidRecieve a payload message and let the app know its availableaddSubsession(InputStream privateKeyStream, Properties opts) Router must be connected or was connected...int[]Blocking.(package private) voidbwReceived(int[] i) called by the message handlerprotected voidchangeState(I2PSessionImpl.State state) static voidvoidconnect()Connect to the router and establish a session.(package private) voiddateUpdated(String routerVersion) (package private) voiddestLookupFailed(long nonce, int code) Called by the message handler on reception of HostReplyMessage(package private) voidCalled by the message handler on reception of DestReplyMessage(package private) voiddestReceived(long nonce, Destination d) Called by the message handler on reception of HostReplyMessage(package private) voidCalled by the message handler on reception of DestReplyMessagevoidTear down the session, and do NOT reconnect.voiddestroySession(boolean sendDisconnect) Tear down the session, and do NOT reconnect.protected voidWill interrupt a connect in progress.voiddisconnected(I2CPMessageReader reader) The I2CPMessageEventListener callback.(package private) I2PAppContextFor SubsessionsRetrieve the decryption PrivateKeyboolean(package private) I2PClientMessageHandlerMapFor Subsessions(package private) LeaseSetRetrieve the destination of the sessionprotected StringgetName()longGet the offline expiration(package private) PropertiesRetrieve the configuration options, filtered.protected Stringtry hard to make a decent identifier as this will appear in error logsRetrieve the signing SigningPrivateKey.(package private) I2CPMessageProducerRetrieve the helper that generates I2CP messagesAlways valid in RouterContext.(package private) SessionIdRetrieve the session's IDbooleanisClosed()Has the session been closed (or not yet connected)? False when open and during transitions.booleanDoes this session have offline and transient keys?longlookupDest(String name) Ask the router to lookup a Destination by hostname.lookupDest(String name, long maxWait) Ask the router to lookup a Destination by hostname.lookupDest(Hash h) Blocking.lookupDest(Hash h, long maxWait) Blocking.lookupDest2(String name, long maxWait) Ask the router to lookup a Destination by hostname.voidmessageReceived(I2CPMessageReader reader, I2CPMessage message) The I2CPMessageEventListener callback.(package private) voidpropogateError(String msg, Throwable error) Pass off the error to the listener Misspelled, oh well.voidreadError(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 voidreceiveStatus(int msgId, long nonce, int status) protected booleanvoidremoveSubsession(I2PSession session) voidreportAbuse(int msgId, int severity) Report abuse with regards to the given messageIdvoid(package private) voidsendMessage(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) voidsendMessage_unchecked(I2CPMessage message) Deliver an I2CP message to the router.(package private) voidsetLeaseSet(LeaseSet ls) void(package private) voidvoidconfigure the listenerprotected booleanprotected voidFire up a periodic task to check for unclaimed messagesbooleantoString()protected voidvoidupdateOptions(Properties options) Update the tunnel and bandwidth settingsprotected voidThrows I2PSessionException if uninitialized, closed or closing.protected voidMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods 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:
-
LISTEN_PORT
public static final int LISTEN_PORT- See Also:
-
-
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 I2PSessionException 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. 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 inPrivateKeyFileoptions- 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 I2PSessionException Router must be connected or was connected... for now.- Specified by:
addSubsessionin 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:
removeSubsessionin interfaceI2PSession- Since:
- 0.9.21
-
getSubsessions
- Specified by:
getSubsessionsin 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:
updateOptionsin 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:
isOfflinein interfaceI2PSession- Since:
- 0.9.38
-
getOfflineExpiration
public long getOfflineExpiration()Description copied from interface:I2PSessionGet the offline expiration- Specified by:
getOfflineExpirationin interfaceI2PSession- Returns:
- Java time (ms) or 0 if not initialized or does not have offline keys
- Since:
- 0.9.38
-
getOfflineSignature
- Specified by:
getOfflineSignaturein interfaceI2PSession- Returns:
- null on error or if not initialized or does not have offline keys
- Since:
- 0.9.38
-
getTransientSigningPublicKey
- Specified by:
getTransientSigningPublicKeyin 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:
connectin interfaceI2PSession- Throws:
I2PSessionException- if there is a configuration error or the router is not reachable
-
waitForDate
- Throws:
InterruptedExceptionIOException- 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:
receiveMessagein 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:
reportAbusein 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:
messageReceivedin 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:
readErrorin interfaceI2CPMessageReader.I2CPMessageEventListener- Parameters:
reader- unusederror- non-null
-
getMyDestination
Retrieve the destination of the session- Specified by:
getMyDestinationin interfaceI2PSession
-
getDecryptionKey
Retrieve the decryption PrivateKey- Specified by:
getDecryptionKeyin interfaceI2PSession
-
getPrivateKey
Retrieve the signing SigningPrivateKey. As of 0.9.38, this will be the transient key if offline signed.- Specified by:
getPrivateKeyin 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:
setSessionListenerin 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:
isClosedin 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:
destroySessionin 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:
disconnectedin 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:
lookupDestin interfaceI2PSession- Returns:
- null on failure
- Throws:
I2PSessionException
-
lookupDest
Blocking.- Specified by:
lookupDestin interfaceI2PSession- Parameters:
maxWait- ms- Returns:
- null on failure
- Throws:
I2PSessionException- Since:
- 0.8.3
-
lookupDest
Ask the router to lookup a Destination by hostname. 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:
lookupDestin interfaceI2PSession- Throws:
I2PSessionException- Since:
- 0.9.11
-
lookupDest
Ask the router to lookup a Destination by hostname. Blocking. See above for details.- Specified by:
lookupDestin interfaceI2PSession- Parameters:
maxWait- ms- Returns:
- null on failure
- Throws:
I2PSessionException- Since:
- 0.9.11
-
lookupDest2
Ask the router to lookup a Destination by hostname. Blocking. See above for details. Same as lookupDest() but with a failure code in the return value- Specified by:
lookupDest2in 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:
bandwidthLimitsin interfaceI2PSession- Returns:
- null on failure
- Throws:
I2PSessionException
-
sendBlindingInfo
- Specified by:
sendBlindingInfoin interfaceI2PSession- Throws:
I2PSessionException- Since:
- 0.9.43
-
getRouterVersion
Always valid in RouterContext. Returns null if not yet connected in I2PAppContext.- Specified by:
getRouterVersionin interfaceI2PSession- Returns:
- null if unknown
- Since:
- 0.9.46
-
updateActivity
protected void updateActivity() -
lastActivity
public long lastActivity() -
setReduced
public void setReduced() -
toString
-