- Direct Known Subclasses:
RouterContext
Provide a base scope for accessing singletons that I2P exposes. Rather than using the traditional singleton, where any component can access the component in question directly, all of those I2P related singletons are exposed through a particular I2PAppContext. This helps not only with understanding their use and the components I2P exposes, but it also allows multiple isolated environments to operate concurrently within the same JVM - particularly useful for stubbing out implementations of the rooted components and simulating the software's interaction between multiple instances.
As a simplification, there is also a global context - if some component needs access to one of the singletons but doesn't have its own context from which to root itself, it binds to the I2PAppContext's getGlobalContext(), which is the first context that was created within the JVM, or a new one if no context existed already. This functionality is often used within the I2P core for. logging - e.g.
private static final Log _log = new Log(someClass.class);
It is for this reason that applications that care about working with multiple contexts should build their own context as soon as possible (within the main(..)) so that any referenced components will latch on to that context instead of instantiating a new one. However, there are situations in which both can be relevant.Field Summary
FieldsModifier and TypeFieldDescriptionprivate AESEngineThe context's AES engine, created on demand.private booleanWhether the AES engine has been created.private final FileDirectory of the running application.private final ClientAppManagerThe context's client app manager.private final FileThe installation's base directory.protected ClockThe context clock, overridden in RouterContext.protected booleanWhether the clock is initialized, used in RouterContext.private final FileDirectory holding i2p.properties.private DSAEngineThe context's DSA engine, created on demand.private booleanWhether the DSA engine has been created.private ElGamalEngineThe context's ElGamal engine, created on demand.private booleanWhether the ElGamal engine has been created.protected static I2PAppContextThe context that components without explicit root are bound.private HMAC256GeneratorThe context's HMAC-SHA256 generator, created on demand.private booleanWhether the HMAC generator has been created.private KeyGeneratorThe context's key generator, created on demand.private booleanWhether the key generator has been created.protected KeyRingThe key ring, overridden in RouterContext.protected booleanWhether the key ring is initialized, used in RouterContext.private final FileDirectory holding the jar files.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final ObjectGuards for the lazily created context components, split from one big lock to avoid deadlocks.private final FileDirectory holding the log files.private LogManagerThe context's log manager, created on demand.private booleanWhether the log manager has been created.private PropertiesConfig properties merged with the system properties.private NamingServiceThe context's naming service, created on demand.private booleanWhether the naming service has been created.protected final I2PPropertiesOverride properties for this context.private final FileDirectory for pid files.private final PortMapperThe context's port mapper for UPnP.private RandomSourceThe context's secure random source, created on demand.private booleanWhether the random source has been created.private final FileDirectory holding the router's egress files.protected SessionKeyManagerThe session key manager.protected booleanWhether the session key manager has been initialized.private SHA256GeneratorThe context's SHA-256 generator, created on demand.private booleanWhether the SHA generator has been created.Shutdown tasks to run on context shutdown.private SimpleTimer2The context's shared timer, created on demand.private booleanWhether the shared timer has been created.private StatManagerThe context's stat manager, created on demand.private booleanWhether the stat manager has been created.private FileDirectory for scratch files.private final RandomRandom for unique temp directory names.Constructor Summary
ConstructorsModifierConstructorDescriptionCreate a brand new context.protectedI2PAppContext(boolean doInit, Properties envProps) Create a brand new context.I2PAppContext(Properties envProps) Create a brand new context.Method Summary
Modifier and TypeMethodDescriptionvoidAdd a callback, which will fire upon changes in the property given in the specific callback.voidaddShutdownTask(Runnable task) WARNING - Shutdown tasks are not executed in an I2PAppContext.aes()Ok, I'll admit it, there is no good reason for having a context specific AES engine.private voidClean up stale i2p- temp directories from previous sessions.The ClientAppManager for this context, non-null in a standalone context and null in a router context.clock()The context's synchronized clock, which is kept context specific only to enable simulators to play with clock skew among different instances.voidDon't rely on deleteOnExit().dsa()Our DSA engine (see HMAC and SHA above).This is the ElGamal engine used within this context.Where applications may store data.This is the installation dir, often referred to as $I2P.booleangetBooleanProperty(String propName) Default false.booleangetBooleanPropertyDefaultTrue(String propName) Boolean property, defaulting to true if not set.The base dir for config files.static I2PAppContextPull the default context, WITHOUT creating a new one.longHow long this router was down before it started, or 0 if unknown.static I2PAppContextPull the default context, creating a new one if necessary, else using the first one created.This is the library dir, which is usually $I2P/lib.Where the router keeps its log directory.Whererouter.pinggoes.Access the configuration attributes of this context, listing the properties provided during the context construction, as well as the ones included in System.getProperties.getProperty(String propName) Access the configuration attributes of this context, using properties provided during the context construction, or falling back on System.getProperty if no properties were provided during construction (or the specified prop wasn't included).final booleangetProperty(String propName, boolean defaultVal) Return a boolean with a boolean default.final floatgetProperty(String propName, float defaultVal) Return a float with a float default.intgetProperty(String propName, int defaultVal) Return an int with an int default.longgetProperty(String propName, long defaultVal) Return a long with a long default.getProperty(String propName, String defaultValue) Access the configuration attributes of this context, using properties provided during the context construction, or falling back on System.getProperty if no properties were provided during construction (or the specified prop wasn't included).Access the configuration attributes of this context, listing the properties provided during the context construction, as well as the ones included in System.getProperties.Where the router keeps its files.List of shutdown tasks.final FileWhere anybody may store temporary data.booleanIs the wrapper present?hmac256()Un-deprecated in 0.9.38.private voidCreates the AES engine.protected voidInitialize the clock.private voidCreates the DSA engine.private voidCreates the ElGamal engine.private voidCreates the key generator.protected voidInitialize the key ring.private voidCreates the log manager from the config.private voidCreates the naming service from the config.private voidCreates the secure random source.protected voidInitialize the session key manager.private voidCreates the SHA-256 generator.private voidCreates the shared timer.private voidCreates the stat manager from the config.Use this to connect to the router in the same JVM.booleanUse this instead of context instanceof RouterContext.Component to generate ElGamal, DSA, and Session keys.keyRing()Basic hash map.Query the log manager for this context, which may in turn have its own set of configuration settings (loaded from the context's properties).Pull up the naming service used in this context.Basic mapping from service names to ports.random()The random source for this context, created on first use.voidremoveShutdownTask(Runnable task) Remove a shutdown task.Determine how much do we want to mess with the keys to turn them into something we can route.The session key manager which coordinates the sessionKey / sessionTag data.protected static booleanDefault context, unless there is one already.voidsetLogManager(LogManager logManager) Overwrites the LogManager instance to be used by the router.sha()Our SHA256 instance (see the hmac discussion for why its context specific).Use instead ofSimpleTimer2.getInstance().The statistics component with which we can track various events over time.
Field Details
_globalAppContext
The context that components without explicit root are bound._overrideProps
Override properties for this context._mergedProps
Config properties merged with the system properties._statManager
The context's stat manager, created on demand._sessionKeyManager
The session key manager._namingService
The context's naming service, created on demand._elGamalEngine
The context's ElGamal engine, created on demand._AESEngine
The context's AES engine, created on demand._logManager
The context's log manager, created on demand._hmac256
The context's HMAC-SHA256 generator, created on demand._sha
The context's SHA-256 generator, created on demand._clock
The context clock, overridden in RouterContext._dsa
The context's DSA engine, created on demand._random
The context's secure random source, created on demand._keyGenerator
The context's key generator, created on demand._keyRing
The key ring, overridden in RouterContext._simpleTimer2
The context's shared timer, created on demand._portMapper
The context's port mapper for UPnP._statManagerInitialized
private volatile boolean _statManagerInitializedWhether the stat manager has been created._sessionKeyManagerInitialized
protected volatile boolean _sessionKeyManagerInitializedWhether the session key manager has been initialized._namingServiceInitialized
private volatile boolean _namingServiceInitializedWhether the naming service has been created._elGamalEngineInitialized
private volatile boolean _elGamalEngineInitializedWhether the ElGamal engine has been created._AESEngineInitialized
private volatile boolean _AESEngineInitializedWhether the AES engine has been created._logManagerInitialized
private volatile boolean _logManagerInitializedWhether the log manager has been created._hmac256Initialized
private volatile boolean _hmac256InitializedWhether the HMAC generator has been created._shaInitialized
private volatile boolean _shaInitializedWhether the SHA generator has been created._clockInitialized
protected volatile boolean _clockInitializedWhether the clock is initialized, used in RouterContext._dsaInitialized
private volatile boolean _dsaInitializedWhether the DSA engine has been created._randomInitialized
private volatile boolean _randomInitializedWhether the random source has been created._keyGeneratorInitialized
private volatile boolean _keyGeneratorInitializedWhether the key generator has been created._keyRingInitialized
protected volatile boolean _keyRingInitializedWhether the key ring is initialized, used in RouterContext._simpleTimer2Initialized
private volatile boolean _simpleTimer2InitializedWhether the shared timer has been created._shutdownTasks
_baseDir
The installation's base directory._configDir
Directory holding i2p.properties._routerDir
Directory holding the router's egress files._pidDir
Directory for pid files._logDir
Directory holding the log files._appDir
Directory of the running application._tmpDir
Directory for scratch files._libDir
Directory holding the jar files._tmpDirRand
Random for unique temp directory names._appManager
The context's client app manager._lock1
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock2
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock3
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock4
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock5
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock7
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock8
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock10
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock11
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock12
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock13
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock14
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock16
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock17
Guards for the lazily created context components, split from one big lock to avoid deadlocks._lock20
Guards for the lazily created context components, split from one big lock to avoid deadlocks.
Constructor Details
I2PAppContext
public I2PAppContext()Create a brand new context. WARNING: In almost all cases, you should use getGlobalContext() instead, to avoid creating additional contexts, which may spawn numerous additional resources and threads, and may be the cause of logging problems or hard-to-isolate bugs.I2PAppContext
Create a brand new context. WARNING: In almost all cases, you should use getGlobalContext() instead, to avoid creating additional contexts, which may spawn numerous additional resources and threads, and may be the cause of logging problems or hard-to-isolate bugs.- Parameters:
envProps- environment properties, may be null
I2PAppContext
Create a brand new context. WARNING: In almost all cases, you should use getGlobalContext() instead, to avoid creating additional contexts, which may spawn numerous additional resources and threads, and may be the cause of logging problems or hard-to-isolate bugs.NOT a public API, for use by RouterContext only, NOT for external use.
- Parameters:
doInit- should this context be used as the global one (if necessary)? Will only apply if there is no global context now.envProps- environment properties, may be null
Method Details
getGlobalContext
Pull the default context, creating a new one if necessary, else using the first one created.Warning - do not save the returned value, or the value of any methods below, in a static field, or you will get the old context if a new router is started in the same JVM after the first is shut down, e.g. on Android.
- Returns:
- the global context for this JVM
setGlobalContext
Default context, unless there is one already. NOT a public API, for use by RouterContext only, NOT for external use.- Parameters:
ctx- context constructed with doInit = false- Returns:
- success (false if previously set)
getCurrentContext
Pull the default context, WITHOUT creating a new one. Use this in static methods used early in router initialization, where creating a context messes things up.- Returns:
- context or null
getBaseDir
This is the installation dir, often referred to as $I2P. Applications should consider this directory read-only and never attempt to write to it. It may actually be read-only on a multi-user installation. The config files in this directory are templates for user installations and should not be accessed by applications. The only thing that may be useful in here is the lib/ dir containing the .jars.- Returns:
- dir constant for the life of the context
getConfigDir
The base dir for config files. Applications may use this to access router configuration files if necessary. Usually ~/.i2p on Linux and %APPDIR%\I2P on Windows. In installations originally installed with 0.7.5 or earlier, and in "portable" installations, this will be the same as the base dir.- Returns:
- dir constant for the life of the context
getRouterDir
Where the router keeps its files. Applications should not use this. The same as the config dir for now.- Returns:
- dir constant for the life of the context
getPIDDir
Whererouter.pinggoes. Applications should not use this. The same as the router dir by default as of 0.8.12 Was the same as the system temp dir prior to that. Which was a problem for multi-user installations.- Returns:
- dir constant for the life of the context
getLogDir
Where the router keeps its log directory. Applications should not use this. The same as the config dir for now. (i.e. ~/.i2p, NOT ~/.i2p/logs).- Returns:
- dir constant for the life of the context
getAppDir
Where applications may store data. The same as the config dir for now, but may change in the future. Apps should be careful not to overwrite router files.- Returns:
- dir constant for the life of the context
getTempDir
Where anybody may store temporary data. This is a directory created in the system temp dir on the first call in this context, and is deleted on JVM exit. Applications should create their own directory inside this directory to avoid collisions with other apps.- Returns:
- dir constant for the life of the context
getLibDir
This is the library dir, which is usually $I2P/lib. It contains all the jars (i.e. the classpath). Most applications will not need this, and must treat this directory as read-only.- Returns:
- dir constant for the life of the context
deleteTempDir
public void deleteTempDir()Don't rely on deleteOnExit().cleanupStaleTempDirs
private void cleanupStaleTempDirs()Clean up stale i2p- temp directories from previous sessions. Since we're starting a new session, all existing i2p-*.tmp folders are from previous sessions and can be safely deleted.getProperty
Access the configuration attributes of this context, using properties provided during the context construction, or falling back on System.getProperty if no properties were provided during construction (or the specified prop wasn't included).- Parameters:
propName- the property name- Returns:
- the property value, or null
getProperty
Access the configuration attributes of this context, using properties provided during the context construction, or falling back on System.getProperty if no properties were provided during construction (or the specified prop wasn't included).- Parameters:
propName- the property namedefaultValue- the default value- Returns:
- the property value, or the default
getProperty
Return an int with an int default.- Parameters:
propName- the property namedefaultVal- the default value- Returns:
- the property value, or the default
getProperty
Return a long with a long default.- Parameters:
propName- the property namedefaultVal- the default value- Returns:
- the property value, or the default
getProperty
Return a float with a float default.- Parameters:
propName- the property namedefaultVal- the default value- Returns:
- the property value, or the default
getProperty
Return a boolean with a boolean default.- Parameters:
propName- the property namedefaultVal- the default value- Returns:
- the property value, or the default
getBooleanProperty
Default false.- Parameters:
propName- the property name- Returns:
- the boolean property
getBooleanPropertyDefaultTrue
Boolean property, defaulting to true if not set.- Parameters:
propName- the property name- Returns:
- the boolean property default true
getPropertyNames
Access the configuration attributes of this context, listing the properties provided during the context construction, as well as the ones included in System.getProperties.WARNING - not overridden in RouterContext, doesn't contain router config settings, use
getProperties()instead.- Returns:
- set of Strings containing the names of defined system properties
getProperties
Access the configuration attributes of this context, listing the properties provided during the context construction, as well as the ones included in System.getProperties.- Returns:
- new Properties with system and context properties
addPropertyCallback
Add a callback, which will fire upon changes in the property given in the specific callback.This is an intentional no-op in a plain I2PAppContext: its properties are only populated in the constructor, so there is nothing to notify. A subclass that allows properties to change at runtime overrides this to register the callback with its I2PProperties - see
RouterContext.addPropertyCallback(I2PProperties.I2PPropertyCallback). Callers that depend on property-change notifications must therefore only do so in such a context.- Parameters:
callback- The implementation of the callback.
statManager
The statistics component with which we can track various events over time.- Returns:
- the stat manager
initializeStatManager
private void initializeStatManager()Creates the stat manager from the config.sessionKeyManager
The session key manager which coordinates the sessionKey / sessionTag data. This component allows transparent operation of the ElGamal/AES+SessionTag algorithm, and contains all of the session tags for one particular application.This is deprecated for client use, it should be used only by the router as its own key manager. Not that clients are doing end-to-end crypto anyway.
For client crypto within the router, use
RouterContext.clientManager()getClientSessionKeyManager(dest)As of 0.9.15, this returns a dummy SessionKeyManager in I2PAppContext. The dummy SKM does NOT handle session tags. Overridden in RouterContext to return the full TransientSessionKeyManager.
- Returns:
- the session key manager
initializeSessionKeyManager
protected void initializeSessionKeyManager()Initialize the session key manager.namingService
Pull up the naming service used in this context. The naming service itself works by querying the context's properties, so those props should be specified to customize the naming service exposed.- Returns:
- the naming service
initializeNamingService
private void initializeNamingService()Creates the naming service from the config.elGamalEngine
This is the ElGamal engine used within this context. While it doesn't really have anything substantial that is context specific (the algorithm just does the algorithm), it does transparently use the context for logging its performance and activity. In addition, the engine can be swapped with the context's properties (though only someone really crazy should mess with it ;).- Returns:
- the ElGamal engine
initializeElGamalEngine
private void initializeElGamalEngine()Creates the ElGamal engine.aes
Ok, I'll admit it, there is no good reason for having a context specific AES engine. We don't really keep stats on it, since its just too fast to matter. Though for the crazy people out there, we do expose a way to disable it.- Returns:
- the AES engine
initializeAESEngine
private void initializeAESEngine()Creates the AES engine.logManager
Query the log manager for this context, which may in turn have its own set of configuration settings (loaded from the context's properties). Each context's logManager keeps its own isolated set of Log instances with their own log levels, output locations, and rotation configuration.- Returns:
- the log manager
initializeLogManager
private void initializeLogManager()Creates the log manager from the config.setLogManager
Overwrites the LogManager instance to be used by the router. This should only be called after the Router is instantiated but before it is started. Calling this at any other time can have unpredictable side effects.- Parameters:
logManager- the LogManager instance to use
hmac256
sha
Our SHA256 instance (see the hmac discussion for why its context specific).- Returns:
- the SHA256 generator
initializeSHA
private void initializeSHA()Creates the SHA-256 generator.dsa
initializeDSA
private void initializeDSA()Creates the DSA engine.keyGenerator
Component to generate ElGamal, DSA, and Session keys. For why it is in the appContext, see the DSA, HMAC, and SHA comments above.- Returns:
- the key generator
initializeKeyGenerator
private void initializeKeyGenerator()Creates the key generator.clock
The context's synchronized clock, which is kept context specific only to enable simulators to play with clock skew among different instances.- Returns:
- the context's Clock, initialized on the first call and shared by every caller
initializeClock
protected void initializeClock()Initialize the clock.routingKeyGenerator
Determine how much do we want to mess with the keys to turn them into something we can route. This is context specific because we may want to test out how things react when peers don't agree on how to skew.As of 0.9.16, returns null in I2PAppContext. You must be in RouterContext to get a generator.
- Returns:
- null always
keyRing
initializeKeyRing
protected void initializeKeyRing()Initialize the key ring.random
The random source for this context, created on first use.The first caller initializes it, holding a lock so that concurrent callers share one instance; every later caller gets that same object. The instance is a FortunaRandomSource, seeded from /dev/urandom and ./prngseed.rnd, so the first call may block while it gathers entropy.
- Returns:
- the random source, non-null
initializeRandom
private void initializeRandom()Creates the secure random source.addShutdownTask
WARNING - Shutdown tasks are not executed in an I2PAppContext. You must be in a RouterContext for the tasks to be executed at shutdown. This method moved from Router in 0.7.1 so that clients may use it without depending onrouter.jar.- Parameters:
task- the Runnable to invoke during shutdown
removeShutdownTask
Remove a shutdown task.- Parameters:
task- the previously added Runnable to drop from the shutdown set
getShutdownTasks
isRouterContext
public boolean isRouterContext()Use this instead of context instanceof RouterContext.- Returns:
- false always in I2PAppContext
internalClientManager
Use this to connect to the router in the same JVM.- Returns:
- always null in I2PAppContext, the client manager if in RouterContext
hasWrapper
public boolean hasWrapper()Is the wrapper present?- Returns:
- true if the wrapper is present
portMapper
simpleTimer2
Use instead ofSimpleTimer2.getInstance().- Returns:
- the SimpleTimer2 instance
initializeSimpleTimer2
private void initializeSimpleTimer2()Creates the shared timer.clientAppManager
The ClientAppManager for this context, non-null in a standalone context and null in a router context. RouterContext overrides this to return the RouterAppManager.- Returns:
- the app manager, null in a router context
getEstimatedDowntime
public long getEstimatedDowntime()How long this router was down before it started, or 0 if unknown.This may be used for a determination of whether to regenerate keys, for example. We use the timestamp of the previous ping file left behind on crash, as set by isOnlyRouterRunning(), if present. Otherwise, the last STOPPED entry in the event log.
May take a while to run the first time, if it has to go through the event log. Once called, the result is cached.
- Returns:
- 0 always in app context