Files
i2p.i2p/router/java/src/net/i2p/router/RouterContext.java

374 lines
15 KiB
Java
Raw Normal View History

package net.i2p.router;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.Hash;
import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
import net.i2p.router.peermanager.Calculator;
import net.i2p.router.peermanager.CapacityCalculator;
import net.i2p.router.peermanager.IntegrationCalculator;
import net.i2p.router.peermanager.PeerManagerFacadeImpl;
import net.i2p.router.peermanager.ProfileManagerImpl;
import net.i2p.router.peermanager.ProfileOrganizer;
import net.i2p.router.peermanager.SpeedCalculator;
import net.i2p.router.transport.CommSystemFacadeImpl;
import net.i2p.router.transport.FIFOBandwidthLimiter;
import net.i2p.router.transport.OutboundMessageRegistry;
import net.i2p.router.transport.VMCommSystem;
2005-02-16 jrandom * (Merged the 0.5-pre branch back into CVS HEAD) * Replaced the old tunnel routing crypto with the one specified in router/doc/tunnel-alt.html, including updates to the web console to view and tweak it. * Provide the means for routers to reject tunnel requests with a wider range of responses: probabalistic rejection, due to approaching overload transient rejection, due to temporary overload bandwidth rejection, due to persistent bandwidth overload critical rejection, due to general router fault (or imminent shutdown) The different responses are factored into the profiles accordingly. * Replaced the old I2CP tunnel related options (tunnels.depthInbound, etc) with a series of new properties, relevent to the new tunnel routing code: inbound.nickname (used on the console) inbound.quantity (# of tunnels to use in any leaseSets) inbound.backupQuantity (# of tunnels to keep in the ready) inbound.length (# of remote peers in the tunnel) inbound.lengthVariance (if > 0, permute the length by adding a random # up to the variance. if < 0, permute the length by adding or subtracting a random # up to the variance) outbound.* (same as the inbound, except for the, uh, outbound tunnels in that client's pool) There are other options, and more will be added later, but the above are the most relevent ones. * Replaced Jetty 4.2.21 with Jetty 5.1.2 * Compress all profile data on disk. * Adjust the reseeding functionality to work even when the JVM's http proxy is set. * Enable a poor-man's interactive-flow in the streaming lib by choking the max window size. * Reduced the default streaming lib max message size to 16KB (though still configurable by the user), also doubling the default maximum window size. * Replaced the RouterIdentity in a Lease with its SHA256 hash. * Reduced the overall I2NP message checksum from a full 32 byte SHA256 to the first byte of the SHA256. * Added a new "netId" flag to let routers drop references to other routers who we won't be able to talk to. * Extended the timestamper to get a second (or third) opinion whenever it wants to actually adjust the clock offset. * Replaced that kludge of a timestamp I2NP message with a full blown DateMessage. * Substantial memory optimizations within the router and the SDK to reduce GC churn. Client apps and the streaming libs have not been tuned, however. * More bugfixes thank you can shake a stick at. 2005-02-13 jrandom * Updated jbigi source to handle 64bit CPUs. The bundled jbigi.jar still only contains 32bit versions, so build your own, placing libjbigi.so in your install dir if necessary. (thanks mule!) * Added support for libjbigi-$os-athlon64 to NativeBigInteger and CPUID (thanks spaetz!)
2005-02-16 22:23:47 +00:00
import net.i2p.router.tunnel.TunnelDispatcher;
import net.i2p.router.tunnel.pool.TunnelPoolManager;
import net.i2p.util.Clock;
import net.i2p.util.KeyRing;
/**
* Build off the core I2P context to provide a root for a router instance to
* coordinate its resources. Router instances themselves should be sure to have
* their own RouterContext, and rooting off of it will allow multiple routers to
* operate in the same JVM without conflict (e.g. sessionTags wont get
* intermingled, nor will their netDbs, jobQueues, or bandwidth limiters).
*
*/
public class RouterContext extends I2PAppContext {
private Router _router;
private ClientManagerFacade _clientManagerFacade;
private ClientMessagePool _clientMessagePool;
private JobQueue _jobQueue;
private InNetMessagePool _inNetMessagePool;
private OutNetMessagePool _outNetMessagePool;
private MessageHistory _messageHistory;
private OutboundMessageRegistry _messageRegistry;
private NetworkDatabaseFacade _netDb;
private KeyManager _keyManager;
private CommSystemFacade _commSystem;
private ProfileOrganizer _profileOrganizer;
private PeerManagerFacade _peerManagerFacade;
private ProfileManager _profileManager;
implemented the FIFO bandwidth limiter which, suprisingly, chokes read/write operations if they would exceed the currently available # of tokens, letting through those operations in the order they are called. like the old trivial bandwidth limiter, this uses a token bucket approach (keeping a pool of 'available' bytes, decrementing on their use and periodically refilling it [up to a max limit, to prevent absurd bursts]). on the other hand, it doesn't have the starvation issues the old one had, which would continue to let small operations go through (e.g. 8 byte write) and potentially block large operations indefinitely (e.g. 32KB write). However, this new version is, how shall I put it, context switch heavy? :) We'll revise with a scheduling / queueing algorithm once we're away from transports that require threads per connection The two directions (input and output) are managed on their own queues, and if/when things are backed up, you can see the details of what operations have been requested on the router console. Since we still need better router throttling code (to reject tunnels and back off more accurately), I've included a minimum KBps on the limiter, currently set to 6KBps both ways. Once there is good throttling code, we can drop that to 1-2KBps, and maybe even less after we do some bandwidth usage tuning. There were also a few minor touch ups to handle message data being discarded earlier than it had been before (since write/read operations can now take a long period of time in the face of contention) The five config properties for the bandwidth limiter are: * i2np.bandwidth.inboundKBytesPerSecond * i2np.bandwidth.outboundKBytesPerSecond (you can guess what those are) * i2np.bandwidth.inboundBurstKBytes * i2np.bandwidth.outboundBurstKBytes the burst KBytes specify how many bytes we'll let accumulate in the bucket, allowing us to burst after a period of inactivity. excess tokens greater than this limit are discarded. * i2np.bandwidth.replenishFrequencyMs this is an internal setting, used to specify how frequently to refil the buckets (min value of 1s, which is the default) You may want to hold off on using these parameters though until the next release, leaving it to the default of unlimited. They are read periodically from the config file however, so you can update them without restart / etc. (if you want to have no limit on the bandwidth, set the KBytesPerSecond to a value <= 0)
2004-07-04 04:33:17 +00:00
private FIFOBandwidthLimiter _bandwidthLimiter;
private TunnelManagerFacade _tunnelManager;
2005-02-16 jrandom * (Merged the 0.5-pre branch back into CVS HEAD) * Replaced the old tunnel routing crypto with the one specified in router/doc/tunnel-alt.html, including updates to the web console to view and tweak it. * Provide the means for routers to reject tunnel requests with a wider range of responses: probabalistic rejection, due to approaching overload transient rejection, due to temporary overload bandwidth rejection, due to persistent bandwidth overload critical rejection, due to general router fault (or imminent shutdown) The different responses are factored into the profiles accordingly. * Replaced the old I2CP tunnel related options (tunnels.depthInbound, etc) with a series of new properties, relevent to the new tunnel routing code: inbound.nickname (used on the console) inbound.quantity (# of tunnels to use in any leaseSets) inbound.backupQuantity (# of tunnels to keep in the ready) inbound.length (# of remote peers in the tunnel) inbound.lengthVariance (if > 0, permute the length by adding a random # up to the variance. if < 0, permute the length by adding or subtracting a random # up to the variance) outbound.* (same as the inbound, except for the, uh, outbound tunnels in that client's pool) There are other options, and more will be added later, but the above are the most relevent ones. * Replaced Jetty 4.2.21 with Jetty 5.1.2 * Compress all profile data on disk. * Adjust the reseeding functionality to work even when the JVM's http proxy is set. * Enable a poor-man's interactive-flow in the streaming lib by choking the max window size. * Reduced the default streaming lib max message size to 16KB (though still configurable by the user), also doubling the default maximum window size. * Replaced the RouterIdentity in a Lease with its SHA256 hash. * Reduced the overall I2NP message checksum from a full 32 byte SHA256 to the first byte of the SHA256. * Added a new "netId" flag to let routers drop references to other routers who we won't be able to talk to. * Extended the timestamper to get a second (or third) opinion whenever it wants to actually adjust the clock offset. * Replaced that kludge of a timestamp I2NP message with a full blown DateMessage. * Substantial memory optimizations within the router and the SDK to reduce GC churn. Client apps and the streaming libs have not been tuned, however. * More bugfixes thank you can shake a stick at. 2005-02-13 jrandom * Updated jbigi source to handle 64bit CPUs. The bundled jbigi.jar still only contains 32bit versions, so build your own, placing libjbigi.so in your install dir if necessary. (thanks mule!) * Added support for libjbigi-$os-athlon64 to NativeBigInteger and CPUID (thanks spaetz!)
2005-02-16 22:23:47 +00:00
private TunnelDispatcher _tunnelDispatcher;
private StatisticsManager _statPublisher;
private Shitlist _shitlist;
private Blocklist _blocklist;
private MessageValidator _messageValidator;
private MessageStateMonitor _messageStateMonitor;
private RouterThrottle _throttle;
private RouterClock _clockX; // LINT field hides another field, hope rename won't break anything.
private Calculator _integrationCalc;
private Calculator _speedCalc;
private Calculator _capacityCalc;
private static List _contexts = new ArrayList(1);
public RouterContext(Router router) { this(router, null); }
public RouterContext(Router router, Properties envProps) {
super(filterProps(envProps));
_router = router;
Big directory rework. Eliminate all uses of the current working directory, and set up multiple directories specified by absolute paths for various uses. Add a WorkingDir class to create a user config directory and migrate files to it for new installs. The directory will be $HOME/.i2p on linux and %APPDIR%\I2P on Windows, or as specified in the system property -Di2p.dir.config=/path/to/i2pdir All files except for the base install and temp files will be in the config directory by default. Temp files will be in a i2p-xxxxx subdirectory of the system temp directory specified by the system property java.io.tmpdir. Convert all file opens in the code to be relative to a specific directory, as specified in the context. Code and applications should never open files relative to the current working directory (e.g. new File("foo")). All files should be accessed in the appropriate context directory, e.g. new File(_context.getAppDir(), "foo"). The router.config file location may be specified as a system property on the java command line with -Drouter.configLocation=/path/to/router.config All directories may be specified as properties in the router.config file. The migration will copy all files from an existing installation, except i2psnark/, with the system property -Di2p.dir.migrate=true. Otherwise it will just set up a new directory with a minimal configuration. The migration will also create a modified wrapper.config and (on linux only) a modified i2prouter script, and place them in the config directory. There are no changes to the installer or the default i2prouter, i2prouter.bat, i2prouter, wrapper.config, runplain.sh, windows service installer/uninstaller, etc. in this checkin. * Directories. These are all set at instantiation and will not be changed by * subsequent property changes. * All properties, if set, should be absolute paths. * * Name Property Method Files * ----- -------- ----- ----- * Base i2p.dir.base getBaseDir() lib/, webapps/, docs/, geoip/, licenses/, ... * Temp i2p.dir.temp getTempDir() Temporary files * Config i2p.dir.config getConfigDir() *.config, hosts.txt, addressbook/, ... * * (the following all default to the same as Config) * * Router i2p.dir.router getRouterDir() netDb/, peerProfiles/, router.*, keyBackup/, ... * Log i2p.dir.log getLogDir() wrapper.log*, logs/ * PID i2p.dir.pid getPIDDir() wrapper *.pid files, router.ping * App i2p.dir.app getAppDir() eepsite/, ... * * Note that we can't control where the wrapper actually puts its files. All these will be set appropriately in a Router Context. In an I2P App Context, all except Temp will be the current working directory. Lightly tested so far, needs much more testing.
2009-06-04 19:14:40 +00:00
// Disabled here so that the router can get a context and get the
// directory locations from it, to do an update, without having
// to init everything. Caller MUST call initAll() afterwards.
// Sorry, this breaks some main() unit tests out there.
//initAll();
_contexts.add(this);
}
/**
* Unless we are explicitly disabling the timestamper, we want to use it.
* We need this now as the new timestamper default is disabled (so we don't
* have each I2PAppContext creating their own SNTP queries all the time)
*
*/
static final Properties filterProps(Properties envProps) {
if (envProps == null)
envProps = new Properties();
if (envProps.getProperty("time.disabled") == null)
envProps.setProperty("time.disabled", "false");
return envProps;
}
Big directory rework. Eliminate all uses of the current working directory, and set up multiple directories specified by absolute paths for various uses. Add a WorkingDir class to create a user config directory and migrate files to it for new installs. The directory will be $HOME/.i2p on linux and %APPDIR%\I2P on Windows, or as specified in the system property -Di2p.dir.config=/path/to/i2pdir All files except for the base install and temp files will be in the config directory by default. Temp files will be in a i2p-xxxxx subdirectory of the system temp directory specified by the system property java.io.tmpdir. Convert all file opens in the code to be relative to a specific directory, as specified in the context. Code and applications should never open files relative to the current working directory (e.g. new File("foo")). All files should be accessed in the appropriate context directory, e.g. new File(_context.getAppDir(), "foo"). The router.config file location may be specified as a system property on the java command line with -Drouter.configLocation=/path/to/router.config All directories may be specified as properties in the router.config file. The migration will copy all files from an existing installation, except i2psnark/, with the system property -Di2p.dir.migrate=true. Otherwise it will just set up a new directory with a minimal configuration. The migration will also create a modified wrapper.config and (on linux only) a modified i2prouter script, and place them in the config directory. There are no changes to the installer or the default i2prouter, i2prouter.bat, i2prouter, wrapper.config, runplain.sh, windows service installer/uninstaller, etc. in this checkin. * Directories. These are all set at instantiation and will not be changed by * subsequent property changes. * All properties, if set, should be absolute paths. * * Name Property Method Files * ----- -------- ----- ----- * Base i2p.dir.base getBaseDir() lib/, webapps/, docs/, geoip/, licenses/, ... * Temp i2p.dir.temp getTempDir() Temporary files * Config i2p.dir.config getConfigDir() *.config, hosts.txt, addressbook/, ... * * (the following all default to the same as Config) * * Router i2p.dir.router getRouterDir() netDb/, peerProfiles/, router.*, keyBackup/, ... * Log i2p.dir.log getLogDir() wrapper.log*, logs/ * PID i2p.dir.pid getPIDDir() wrapper *.pid files, router.ping * App i2p.dir.app getAppDir() eepsite/, ... * * Note that we can't control where the wrapper actually puts its files. All these will be set appropriately in a Router Context. In an I2P App Context, all except Temp will be the current working directory. Lightly tested so far, needs much more testing.
2009-06-04 19:14:40 +00:00
public void initAll() {
if ("false".equals(getProperty("i2p.dummyClientFacade", "false")))
_clientManagerFacade = new ClientManagerFacadeImpl(this);
else
_clientManagerFacade = new DummyClientManagerFacade(this);
_clientMessagePool = new ClientMessagePool(this);
_jobQueue = new JobQueue(this);
_inNetMessagePool = new InNetMessagePool(this);
_outNetMessagePool = new OutNetMessagePool(this);
_messageHistory = new MessageHistory(this);
_messageRegistry = new OutboundMessageRegistry(this);
_messageStateMonitor = new MessageStateMonitor(this);
if ("false".equals(getProperty("i2p.dummyNetDb", "false")))
_netDb = new FloodfillNetworkDatabaseFacade(this); // new KademliaNetworkDatabaseFacade(this);
else
_netDb = new DummyNetworkDatabaseFacade(this);
_keyManager = new KeyManager(this);
if ("false".equals(getProperty("i2p.vmCommSystem", "false")))
_commSystem = new CommSystemFacadeImpl(this);
else
_commSystem = new VMCommSystem(this);
_profileOrganizer = new ProfileOrganizer(this);
if ("false".equals(getProperty("i2p.dummyPeerManager", "false")))
_peerManagerFacade = new PeerManagerFacadeImpl(this);
else
_peerManagerFacade = new DummyPeerManagerFacade();
_profileManager = new ProfileManagerImpl(this);
implemented the FIFO bandwidth limiter which, suprisingly, chokes read/write operations if they would exceed the currently available # of tokens, letting through those operations in the order they are called. like the old trivial bandwidth limiter, this uses a token bucket approach (keeping a pool of 'available' bytes, decrementing on their use and periodically refilling it [up to a max limit, to prevent absurd bursts]). on the other hand, it doesn't have the starvation issues the old one had, which would continue to let small operations go through (e.g. 8 byte write) and potentially block large operations indefinitely (e.g. 32KB write). However, this new version is, how shall I put it, context switch heavy? :) We'll revise with a scheduling / queueing algorithm once we're away from transports that require threads per connection The two directions (input and output) are managed on their own queues, and if/when things are backed up, you can see the details of what operations have been requested on the router console. Since we still need better router throttling code (to reject tunnels and back off more accurately), I've included a minimum KBps on the limiter, currently set to 6KBps both ways. Once there is good throttling code, we can drop that to 1-2KBps, and maybe even less after we do some bandwidth usage tuning. There were also a few minor touch ups to handle message data being discarded earlier than it had been before (since write/read operations can now take a long period of time in the face of contention) The five config properties for the bandwidth limiter are: * i2np.bandwidth.inboundKBytesPerSecond * i2np.bandwidth.outboundKBytesPerSecond (you can guess what those are) * i2np.bandwidth.inboundBurstKBytes * i2np.bandwidth.outboundBurstKBytes the burst KBytes specify how many bytes we'll let accumulate in the bucket, allowing us to burst after a period of inactivity. excess tokens greater than this limit are discarded. * i2np.bandwidth.replenishFrequencyMs this is an internal setting, used to specify how frequently to refil the buckets (min value of 1s, which is the default) You may want to hold off on using these parameters though until the next release, leaving it to the default of unlimited. They are read periodically from the config file however, so you can update them without restart / etc. (if you want to have no limit on the bandwidth, set the KBytesPerSecond to a value <= 0)
2004-07-04 04:33:17 +00:00
_bandwidthLimiter = new FIFOBandwidthLimiter(this);
if ("false".equals(getProperty("i2p.dummyTunnelManager", "false")))
_tunnelManager = new TunnelPoolManager(this);
else
_tunnelManager = new DummyTunnelManagerFacade();
2005-02-16 jrandom * (Merged the 0.5-pre branch back into CVS HEAD) * Replaced the old tunnel routing crypto with the one specified in router/doc/tunnel-alt.html, including updates to the web console to view and tweak it. * Provide the means for routers to reject tunnel requests with a wider range of responses: probabalistic rejection, due to approaching overload transient rejection, due to temporary overload bandwidth rejection, due to persistent bandwidth overload critical rejection, due to general router fault (or imminent shutdown) The different responses are factored into the profiles accordingly. * Replaced the old I2CP tunnel related options (tunnels.depthInbound, etc) with a series of new properties, relevent to the new tunnel routing code: inbound.nickname (used on the console) inbound.quantity (# of tunnels to use in any leaseSets) inbound.backupQuantity (# of tunnels to keep in the ready) inbound.length (# of remote peers in the tunnel) inbound.lengthVariance (if > 0, permute the length by adding a random # up to the variance. if < 0, permute the length by adding or subtracting a random # up to the variance) outbound.* (same as the inbound, except for the, uh, outbound tunnels in that client's pool) There are other options, and more will be added later, but the above are the most relevent ones. * Replaced Jetty 4.2.21 with Jetty 5.1.2 * Compress all profile data on disk. * Adjust the reseeding functionality to work even when the JVM's http proxy is set. * Enable a poor-man's interactive-flow in the streaming lib by choking the max window size. * Reduced the default streaming lib max message size to 16KB (though still configurable by the user), also doubling the default maximum window size. * Replaced the RouterIdentity in a Lease with its SHA256 hash. * Reduced the overall I2NP message checksum from a full 32 byte SHA256 to the first byte of the SHA256. * Added a new "netId" flag to let routers drop references to other routers who we won't be able to talk to. * Extended the timestamper to get a second (or third) opinion whenever it wants to actually adjust the clock offset. * Replaced that kludge of a timestamp I2NP message with a full blown DateMessage. * Substantial memory optimizations within the router and the SDK to reduce GC churn. Client apps and the streaming libs have not been tuned, however. * More bugfixes thank you can shake a stick at. 2005-02-13 jrandom * Updated jbigi source to handle 64bit CPUs. The bundled jbigi.jar still only contains 32bit versions, so build your own, placing libjbigi.so in your install dir if necessary. (thanks mule!) * Added support for libjbigi-$os-athlon64 to NativeBigInteger and CPUID (thanks spaetz!)
2005-02-16 22:23:47 +00:00
_tunnelDispatcher = new TunnelDispatcher(this);
_statPublisher = new StatisticsManager(this);
_shitlist = new Shitlist(this);
_blocklist = new Blocklist(this);
_messageValidator = new MessageValidator(this);
//_throttle = new RouterThrottleImpl(this);
_throttle = new RouterDoSThrottle(this);
_integrationCalc = new IntegrationCalculator(this);
_speedCalc = new SpeedCalculator(this);
_capacityCalc = new CapacityCalculator(this);
}
/**
* Retrieve the list of router contexts currently instantiated in this JVM.
* This will always contain only one item (except when a simulation per the
* MultiRouter is going on), and the list should only be modified when a new
* context is created or a router is shut down.
*
*/
public static List listContexts() { return _contexts; }
/** what router is this context working for? */
public Router router() { return _router; }
/** convenience method for querying the router's ident */
public Hash routerHash() { return _router.getRouterInfo().getIdentity().getHash(); }
/**
* How are we coordinating clients for the router?
*/
public ClientManagerFacade clientManager() { return _clientManagerFacade; }
/**
* Where do we toss messages for the clients (and where do we get client messages
* to forward on from)?
*/
public ClientMessagePool clientMessagePool() { return _clientMessagePool; }
/**
* Where do we get network messages from (aka where does the comm system dump what
* it reads)?
*/
public InNetMessagePool inNetMessagePool() { return _inNetMessagePool; }
/**
* Where do we put messages that the router wants to forwards onto the network?
*/
public OutNetMessagePool outNetMessagePool() { return _outNetMessagePool; }
/**
* Tracker component for monitoring what messages are wrapped in what containers
* and how they proceed through the network. This is fully for debugging, as when
* a large portion of the network tracks their messages through this messageHistory
* and submits their logs, we can correlate them and watch as messages flow from
* hop to hop.
*/
public MessageHistory messageHistory() { return _messageHistory; }
/**
* The registry is used by outbound messages to wait for replies.
*/
public OutboundMessageRegistry messageRegistry() { return _messageRegistry; }
/**
* The monitor keeps track of inbound and outbound messages currently held in
* memory / queued for processing. We'll use this to throttle the router so
* we don't overflow.
*
*/
public MessageStateMonitor messageStateMonitor() { return _messageStateMonitor; }
/**
* Our db cache
*/
public NetworkDatabaseFacade netDb() { return _netDb; }
/**
* The actual driver of the router, where all jobs are enqueued and processed.
*/
public JobQueue jobQueue() { return _jobQueue; }
/**
* Coordinates the router's ElGamal and DSA keys, as well as any keys given
* to it by clients as part of a LeaseSet.
*/
public KeyManager keyManager() { return _keyManager; }
/**
* How do we pass messages from our outNetMessagePool to another router
*/
public CommSystemFacade commSystem() { return _commSystem; }
/**
* Organize the peers we know about into various tiers, profiling their
* performance and sorting them accordingly.
*/
public ProfileOrganizer profileOrganizer() { return _profileOrganizer; }
/**
* Minimal interface for selecting peers for various tasks based on given
* criteria. This is kept seperate from the profile organizer since this
* logic is independent of how the peers are organized (or profiled even).
*/
public PeerManagerFacade peerManager() { return _peerManagerFacade; }
/**
* Expose a simple API for various router components to take note of
* particular events that a peer enacts (sends us a message, agrees to
* participate in a tunnel, etc).
*/
public ProfileManager profileManager() { return _profileManager; }
/**
* Coordinate this router's bandwidth limits
*/
implemented the FIFO bandwidth limiter which, suprisingly, chokes read/write operations if they would exceed the currently available # of tokens, letting through those operations in the order they are called. like the old trivial bandwidth limiter, this uses a token bucket approach (keeping a pool of 'available' bytes, decrementing on their use and periodically refilling it [up to a max limit, to prevent absurd bursts]). on the other hand, it doesn't have the starvation issues the old one had, which would continue to let small operations go through (e.g. 8 byte write) and potentially block large operations indefinitely (e.g. 32KB write). However, this new version is, how shall I put it, context switch heavy? :) We'll revise with a scheduling / queueing algorithm once we're away from transports that require threads per connection The two directions (input and output) are managed on their own queues, and if/when things are backed up, you can see the details of what operations have been requested on the router console. Since we still need better router throttling code (to reject tunnels and back off more accurately), I've included a minimum KBps on the limiter, currently set to 6KBps both ways. Once there is good throttling code, we can drop that to 1-2KBps, and maybe even less after we do some bandwidth usage tuning. There were also a few minor touch ups to handle message data being discarded earlier than it had been before (since write/read operations can now take a long period of time in the face of contention) The five config properties for the bandwidth limiter are: * i2np.bandwidth.inboundKBytesPerSecond * i2np.bandwidth.outboundKBytesPerSecond (you can guess what those are) * i2np.bandwidth.inboundBurstKBytes * i2np.bandwidth.outboundBurstKBytes the burst KBytes specify how many bytes we'll let accumulate in the bucket, allowing us to burst after a period of inactivity. excess tokens greater than this limit are discarded. * i2np.bandwidth.replenishFrequencyMs this is an internal setting, used to specify how frequently to refil the buckets (min value of 1s, which is the default) You may want to hold off on using these parameters though until the next release, leaving it to the default of unlimited. They are read periodically from the config file however, so you can update them without restart / etc. (if you want to have no limit on the bandwidth, set the KBytesPerSecond to a value <= 0)
2004-07-04 04:33:17 +00:00
public FIFOBandwidthLimiter bandwidthLimiter() { return _bandwidthLimiter; }
/**
* Coordinate this router's tunnels (its pools, participation, backup, etc).
* Any configuration for the tunnels is rooted from the context's properties
*/
public TunnelManagerFacade tunnelManager() { return _tunnelManager; }
2005-02-16 jrandom * (Merged the 0.5-pre branch back into CVS HEAD) * Replaced the old tunnel routing crypto with the one specified in router/doc/tunnel-alt.html, including updates to the web console to view and tweak it. * Provide the means for routers to reject tunnel requests with a wider range of responses: probabalistic rejection, due to approaching overload transient rejection, due to temporary overload bandwidth rejection, due to persistent bandwidth overload critical rejection, due to general router fault (or imminent shutdown) The different responses are factored into the profiles accordingly. * Replaced the old I2CP tunnel related options (tunnels.depthInbound, etc) with a series of new properties, relevent to the new tunnel routing code: inbound.nickname (used on the console) inbound.quantity (# of tunnels to use in any leaseSets) inbound.backupQuantity (# of tunnels to keep in the ready) inbound.length (# of remote peers in the tunnel) inbound.lengthVariance (if > 0, permute the length by adding a random # up to the variance. if < 0, permute the length by adding or subtracting a random # up to the variance) outbound.* (same as the inbound, except for the, uh, outbound tunnels in that client's pool) There are other options, and more will be added later, but the above are the most relevent ones. * Replaced Jetty 4.2.21 with Jetty 5.1.2 * Compress all profile data on disk. * Adjust the reseeding functionality to work even when the JVM's http proxy is set. * Enable a poor-man's interactive-flow in the streaming lib by choking the max window size. * Reduced the default streaming lib max message size to 16KB (though still configurable by the user), also doubling the default maximum window size. * Replaced the RouterIdentity in a Lease with its SHA256 hash. * Reduced the overall I2NP message checksum from a full 32 byte SHA256 to the first byte of the SHA256. * Added a new "netId" flag to let routers drop references to other routers who we won't be able to talk to. * Extended the timestamper to get a second (or third) opinion whenever it wants to actually adjust the clock offset. * Replaced that kludge of a timestamp I2NP message with a full blown DateMessage. * Substantial memory optimizations within the router and the SDK to reduce GC churn. Client apps and the streaming libs have not been tuned, however. * More bugfixes thank you can shake a stick at. 2005-02-13 jrandom * Updated jbigi source to handle 64bit CPUs. The bundled jbigi.jar still only contains 32bit versions, so build your own, placing libjbigi.so in your install dir if necessary. (thanks mule!) * Added support for libjbigi-$os-athlon64 to NativeBigInteger and CPUID (thanks spaetz!)
2005-02-16 22:23:47 +00:00
/**
* Handle tunnel messages, as well as coordinate the gateways
*/
public TunnelDispatcher tunnelDispatcher() { return _tunnelDispatcher; }
/**
* If the router is configured to, gather up some particularly tasty morsels
* regarding the stats managed and offer to publish them into the routerInfo.
*/
public StatisticsManager statPublisher() { return _statPublisher; }
/**
* who does this peer hate?
*/
public Shitlist shitlist() { return _shitlist; }
public Blocklist blocklist() { return _blocklist; }
/**
* The router keeps track of messages it receives to prevent duplicates, as
* well as other criteria for "validity".
*/
public MessageValidator messageValidator() { return _messageValidator; }
/**
* Component to coordinate our accepting/rejecting of requests under load
*
*/
public RouterThrottle throttle() { return _throttle; }
/** how do we rank the integration of profiles? */
public Calculator integrationCalculator() { return _integrationCalc; }
/** how do we rank the speed of profiles? */
public Calculator speedCalculator() { return _speedCalc; }
/** how do we rank the capacity of profiles? */
public Calculator capacityCalculator() { return _capacityCalc; }
@Override
public String toString() {
StringBuilder buf = new StringBuilder(512);
buf.append("RouterContext: ").append(super.toString()).append('\n');
buf.append(_router).append('\n');
buf.append(_clientManagerFacade).append('\n');
buf.append(_clientMessagePool).append('\n');
buf.append(_jobQueue).append('\n');
buf.append(_inNetMessagePool).append('\n');
buf.append(_outNetMessagePool).append('\n');
buf.append(_messageHistory).append('\n');
buf.append(_messageRegistry).append('\n');
buf.append(_netDb).append('\n');
buf.append(_keyManager).append('\n');
buf.append(_commSystem).append('\n');
buf.append(_profileOrganizer).append('\n');
buf.append(_peerManagerFacade).append('\n');
buf.append(_profileManager).append('\n');
buf.append(_bandwidthLimiter).append('\n');
buf.append(_tunnelManager).append('\n');
buf.append(_statPublisher).append('\n');
buf.append(_shitlist).append('\n');
buf.append(_messageValidator).append('\n');
buf.append(_integrationCalc).append('\n');
buf.append(_speedCalc).append('\n');
return buf.toString();
}
/**
* Tie in the router's config as properties, as well as whatever the
* I2PAppContext says.
*
*/
@Override
public String getProperty(String propName) {
if (_router != null) {
String val = _router.getConfigSetting(propName);
if (val != null) return val;
}
return super.getProperty(propName);
}
/**
* Tie in the router's config as properties, as well as whatever the
* I2PAppContext says.
*
*/
@Override
public String getProperty(String propName, String defaultVal) {
if (_router != null) {
String val = _router.getConfigSetting(propName);
if (val != null) return val;
}
return super.getProperty(propName, defaultVal);
}
/**
* Return an int with an int default
*/
@Override
public int getProperty(String propName, int defaultVal) {
if (_router != null) {
String val = _router.getConfigSetting(propName);
if (val != null) {
int ival = defaultVal;
try {
ival = Integer.parseInt(val);
} catch (NumberFormatException nfe) {}
return ival;
}
}
return super.getProperty(propName, defaultVal);
}
/**
* The context's synchronized clock, which is kept context specific only to
* enable simulators to play with clock skew among different instances.
*
* It wouldn't be necessary to override clock(), except for the reason
* that it triggers initializeClock() of which we definitely
* need the local version to run.
*/
@Override
public Clock clock() {
if (!_clockInitialized) initializeClock();
return _clockX;
}
@Override
protected void initializeClock() {
synchronized (this) {
if (_clockX == null)
_clockX = new RouterClock(this);
_clockInitialized = true;
}
}
/** override to support storage in router.config */
@Override
public KeyRing keyRing() {
if (!_keyRingInitialized)
initializeKeyRing();
return _keyRing;
}
@Override
protected void initializeKeyRing() {
synchronized (this) {
if (_keyRing == null)
_keyRing = new PersistentKeyRing(this);
_keyRingInitialized = true;
}
}
}