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 classI2PSessionImpl.AvailabilityNotifierThis notifies the client of payload messages.protected static classI2PSessionImpl.State
-
Field Summary
Fields Modifier and Type Field Description protected I2PSessionImpl.AvailabilityNotifier_availabilityNotifierthread that we tell when new messages are available who then tells us to fetch them.protected Map<Long,MessagePayloadMessage>_availableMessagesmap of Long --> MessagePayloadMessageprotected int[]_bwLimitsprotected Object_bwReceivedLockprotected I2PAppContext_contextused to separate things out so we can get rid of singletonsprotected I2PClientMessageHandlerMap_handlerMapprotected String_hostnamehostname of router - will be null if in RouterContextprotected LeaseSet_leaseSetcurrently granted lease set, or nullprotected Object_leaseSetWaitmonitor for waiting until a lease set has been grantedprotected Log_logprotected LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter>_pendingLookupshashes of lookups we are waiting forprotected int_portNumport num to router - will be 0 if in RouterContextprotected I2CPMessageProducer_producerclass that generates new messagesprotected I2CPMessageQueue_queueUsed for internal connections to the router.protected I2CPMessageReader_readerreader that always searches for messagesprotected I2PSessionListener_sessionListenerwho we send events toprotected Socket_socketsocket for commprotected I2PSessionImpl.State_stateprotected Object_stateLockprotected SigningPublicKey_transientSigningPublicKeyprotected ClientWriterRunner_writerwriter message queueprotected static intCACHE_MAX_SIZEstatic intLISTEN_PORTprotected static StringPROP_DOMAIN_SOCKETUse Unix domain socket (or similar) to connect to a router-
Fields 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 protectedI2PSessionImpl(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
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description voidaddNewMessage(MessagePayloadMessage msg)Recieve a payload message and let the app know its availableI2PSessionaddSubsession(InputStream privateKeyStream, Properties opts)Router must be connected or was connected...int[]bandwidthLimits()Blocking.(package private) voidbwReceived(int[] i)called by the message handlerprotected voidchangeState(I2PSessionImpl.State state)static voidclearCache()voidconnect()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) voiddestLookupFailed(Hash h)Called 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) voiddestReceived(Destination d)Called by the message handler on reception of DestReplyMessagevoiddestroySession()Tear down the session, and do NOT reconnect.voiddestroySession(boolean sendDisconnect)Tear down the session, and do NOT reconnect.protected voiddisconnect()Will interrupt a connect in progress.voiddisconnected(I2CPMessageReader reader)The I2CPMessageEventListener callback.(package private) I2PAppContextgetContext()For SubsessionsPrivateKeygetDecryptionKey()Retrieve the decryption PrivateKeybooleangetFastReceive()(package private) I2PClientMessageHandlerMapgetHandlerMap()For Subsessions(package private) LeaseSetgetLeaseSet()DestinationgetMyDestination()Retrieve the destination of the sessionprotected StringgetName()longgetOfflineExpiration()Get the offline expirationSignaturegetOfflineSignature()(package private) PropertiesgetOptions()Retrieve the configuration options, filtered.protected StringgetPrefix()try hard to make a decent identifier as this will appear in error logsSigningPrivateKeygetPrivateKey()Retrieve the signing SigningPrivateKey.(package private) I2CPMessageProducergetProducer()Retrieve the helper that generates I2CP messagesStringgetRouterVersion()Always valid in RouterContext.(package private) SessionIdgetSessionId()Retrieve the session's IDList<I2PSession>getSubsessions()SigningPublicKeygetTransientSigningPublicKey()booleanisClosed()Has the session been closed (or not yet connected)? False when open and during transitions.booleanisOffline()Does this session have offline and transient keys?longlastActivity()DestinationlookupDest(String name)Ask the router to lookup a Destination by hostname.DestinationlookupDest(String name, long maxWait)Ask the router to lookup a Destination by hostname.DestinationlookupDest(Hash h)Blocking.DestinationlookupDest(Hash h, long maxWait)Blocking.LookupResultlookupDest2(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 booleanreconnect()voidremoveSubsession(I2PSession session)voidreportAbuse(int msgId, int severity)Report abuse with regards to the given messageIdvoidsendBlindingInfo(BlindData bd)(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)voidsetReduced()(package private) voidsetSessionId(SessionId id)voidsetSessionListener(I2PSessionListener lsnr)configure the listenerprotected booleanshouldReconnect()protected voidstartVerifyUsage()Fire up a periodic task to check for unclaimed messagesbooleansupportsLS2()StringtoString()protected voidupdateActivity()voidupdateOptions(Properties options)Update the tunnel and bandwidth settingsprotected voidverifyOpen()Throws I2PSessionException if uninitialized, closed or closing.protected voidwaitForDate()-
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 Detail
-
_log
protected final Log _log
-
_leaseSet
protected volatile LeaseSet _leaseSet
currently granted lease set, or null
-
_transientSigningPublicKey
protected SigningPublicKey _transientSigningPublicKey
-
_hostname
protected final String _hostname
hostname of router - will be null if in RouterContext
-
_portNum
protected final int _portNum
port num to router - will be 0 if in RouterContext
-
_socket
protected Socket _socket
socket for comm
-
_reader
protected I2CPMessageReader _reader
reader that always searches for messages
-
_writer
protected ClientWriterRunner _writer
writer message queue
-
_queue
protected I2CPMessageQueue _queue
Used for internal connections to the router. If this is set, _socket and _writer will be null.- Since:
- 0.8.3
-
_sessionListener
protected I2PSessionListener _sessionListener
who we send events to
-
_producer
protected final I2CPMessageProducer _producer
class that generates new messages
-
_availableMessages
protected Map<Long,MessagePayloadMessage> _availableMessages
map of Long --> MessagePayloadMessage
-
_pendingLookups
protected final LinkedBlockingQueue<net.i2p.client.impl.I2PSessionImpl.LookupWaiter> _pendingLookups
hashes of lookups we are waiting for
-
_bwReceivedLock
protected final Object _bwReceivedLock
-
_bwLimits
protected volatile int[] _bwLimits
-
_handlerMap
protected final I2PClientMessageHandlerMap _handlerMap
-
_context
protected final I2PAppContext _context
used to separate things out so we can get rid of singletons
-
_leaseSetWait
protected final Object _leaseSetWait
monitor for waiting until a lease set has been granted
-
_state
protected I2PSessionImpl.State _state
-
_stateLock
protected final Object _stateLock
-
_availabilityNotifier
protected I2PSessionImpl.AvailabilityNotifier _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
protected static final String 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 Detail
-
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 Detail
-
dateUpdated
void dateUpdated(String routerVersion)
- 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
public void removeSubsession(I2PSession session)
- Specified by:
removeSubsessionin interfaceI2PSession- Since:
- 0.9.21
-
getSubsessions
public List<I2PSession> getSubsessions()
- Specified by:
getSubsessionsin interfaceI2PSession- Returns:
- a list of subsessions, non-null, does not include the primary session
- Since:
- 0.9.21
-
updateOptions
public void updateOptions(Properties options)
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
void setLeaseSet(LeaseSet ls)
-
getLeaseSet
LeaseSet getLeaseSet()
-
changeState
protected void changeState(I2PSessionImpl.State state)
-
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
public Signature getOfflineSignature()
- Specified by:
getOfflineSignaturein interfaceI2PSession- Returns:
- null on error or if not initialized or does not have offline keys
- Since:
- 0.9.38
-
getTransientSigningPublicKey
public SigningPublicKey getTransientSigningPublicKey()
- Specified by:
getTransientSigningPublicKeyin interfaceI2PSession- Returns:
- null on error or if not initialized or does not have offline keys
- Since:
- 0.9.38
-
connect
public void connect() throws I2PSessionExceptionConnect 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
protected void waitForDate() throws InterruptedException, IOException- Throws:
InterruptedExceptionIOException- Since:
- 0.9.11 moved from connect()
-
receiveMessage
public byte[] receiveMessage(int msgId) throws I2PSessionExceptionPull 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
public void reportAbuse(int msgId, int severity) throws I2PSessionExceptionReport 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
public void addNewMessage(MessagePayloadMessage msg)
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
public void messageReceived(I2CPMessageReader reader, I2CPMessage message)
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
public void readError(I2CPMessageReader reader, Exception error)
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
public Destination getMyDestination()
Retrieve the destination of the session- Specified by:
getMyDestinationin interfaceI2PSession
-
getDecryptionKey
public PrivateKey getDecryptionKey()
Retrieve the decryption PrivateKey- Specified by:
getDecryptionKeyin interfaceI2PSession
-
getPrivateKey
public SigningPrivateKey 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
void setSessionId(SessionId id)
-
setSessionListener
public void setSessionListener(I2PSessionListener lsnr)
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
protected void verifyOpen() throws I2PSessionExceptionThrows I2PSessionException if uninitialized, closed or closing. Blocks if opening.- Throws:
I2PSessionException- Since:
- 0.9.23
-
sendMessage
void sendMessage(I2CPMessage message) throws I2PSessionException
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
void sendMessage_unchecked(I2CPMessage message) throws I2PSessionException
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
void propogateError(String msg, Throwable error)
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
public void disconnected(I2CPMessageReader reader)
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
protected String getPrefix()
try hard to make a decent identifier as this will appear in error logs
-
getName
protected String getName()
- Since:
- 0.9.46
-
destReceived
void destReceived(Destination d)
Called by the message handler on reception of DestReplyMessage- Parameters:
d- non-null
-
destLookupFailed
void destLookupFailed(Hash h)
Called by the message handler on reception of DestReplyMessage- Parameters:
h- non-null
-
destReceived
void destReceived(long nonce, Destination d)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
public Destination lookupDest(Hash h) throws I2PSessionException
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
public Destination lookupDest(Hash h, long maxWait) throws I2PSessionException
Blocking.- Specified by:
lookupDestin interfaceI2PSession- Parameters:
maxWait- ms- Returns:
- null on failure
- Throws:
I2PSessionException- Since:
- 0.8.3
-
lookupDest
public Destination lookupDest(String name) throws I2PSessionException
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
public Destination lookupDest(String name, long maxWait) throws I2PSessionException
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
public LookupResult lookupDest2(String name, long maxWait) throws I2PSessionException
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
public int[] bandwidthLimits() throws I2PSessionExceptionBlocking. 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
public void sendBlindingInfo(BlindData bd) throws I2PSessionException
- Specified by:
sendBlindingInfoin interfaceI2PSession- Throws:
I2PSessionException- Since:
- 0.9.43
-
getRouterVersion
public String 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()
-
-