I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 29b599bc authored by dev's avatar dev
Browse files

merge of '80aa8cd653ef7ee96cd6603b9646c53b2ff84760'

     and 'da25b770e65a36f3056b905cc6b96be431076a6b'
parents f939f689 6bbd34ee
No related branches found
No related tags found
No related merge requests found
package net.i2p.router;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Properties;
import java.util.Scanner;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.RouterInfo;
import net.i2p.router.Router;
import net.i2p.util.Log;
/**
......@@ -16,7 +23,7 @@ import net.i2p.util.Log;
* contained in them are used for the context's getProperty(name)). <p />
*
* <b>Usage:</b><pre>
* MultiRouter globalContextFile routerContextFile[ routerContextFile]*
* MultiRouter numberRouters
* </pre>
*
* Each routerContext specified is used to boot up a single router. It is HIGHLY
......@@ -36,72 +43,181 @@ import net.i2p.util.Log;
* that need the encryption enabled). To run a client app through a router that
* has i2p.encryption=off, you should also add that line to the client's JVM
* (for example, <code>java -Di2p.encryption=off -jar lib/i2ptunnel.jar</code>).<p />
*
* To make the router console work, either run from a directory containing
* lib/, webapps/, docs/, etc., or point i2p.dir.base to a directory containing the
* above.
*
* The multirouter waits until all of the routers are shut down (which none will
* do on their own, so as before, you'll want to kill the proc or ^C it).
*/
public class MultiRouter {
private static Log _log;
private static ArrayList _routers = new ArrayList(8);
private static final int BASE_PORT = 5000;
private static int nbrRouters;
private static PrintStream _out;
private static ArrayList<Router> _routers = new ArrayList<Router>(8);
private static I2PAppContext _defaultContext;
public static void main(String args[]) {
if ( (args == null) || (args.length <= 1) ) {
if ( (args == null) || (args.length < 1) ) {
usage();
return;
}
Scanner scan = new Scanner(args[0]);
if (!scan.hasNextInt()) {
usage();
return;
}
nbrRouters = scan.nextInt();
if (nbrRouters < 0) {
usage();
return;
}
_defaultContext = new I2PAppContext(getEnv(args[0]));
_log = _defaultContext.logManager().getLog(MultiRouter.class);
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
_out = System.out;
buildClientProps(0);
_defaultContext = new I2PAppContext(buildRouterProps(0));
_defaultContext.clock().setOffset(0);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
Thread.currentThread().setName("Router* Shutdown");
try { Thread.sleep(120*1000); } catch (InterruptedException ie) {}
Runtime.getRuntime().halt(-1);
_out.println("Shutting down in a few moments..");
for(Router r : _routers) {
r.shutdown(-1);
}
try { Thread.sleep(1500); } catch (InterruptedException ie) {}
Runtime.getRuntime().halt(0);
}
});
for (int i = 1; i < args.length; i++) {
Router router = new Router(getEnv(args[i]));
for (int i = 0; i < nbrRouters; i++) {
Router router = new Router(buildRouterProps(i));
router.setKillVMOnEnd(false);
_routers.add(router);
_log.info("Router " + i + " created from " + args[i]);
//try { Thread.sleep(2*1000); } catch (InterruptedException ie) {}
_out.println("Router " + i + " was created");
}
for (int i = 0; i < _routers.size(); i++) {
Router r = (Router)_routers.get(i);
for (int i = 0; i < nbrRouters; i++) {
Router r = _routers.get(i);
long offset = r.getContext().random().nextLong(Router.CLOCK_FUDGE_FACTOR/2);
if (r.getContext().random().nextBoolean())
offset = 0 - offset;
r.getContext().clock().setOffset(offset, true);
r.runRouter();
_log.info("Router " + i + " started with clock offset " + offset);
try { Thread.sleep(2*1000 + new java.util.Random().nextInt(2)*1000); } catch (InterruptedException ie) {}
_out.println("Router " + i + " was started with time offset " + offset);
}
_log.info("All " + _routers.size() + " routers started up");
_out.println("All routers have been started");
/* Wait for routers to start services and generate keys.. */
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
internalReseed();
waitForCompletion();
}
private static Properties getEnv(String filename) {
private static void internalReseed() {
HashSet<RouterInfo> riSet = new HashSet<RouterInfo>();
for(Router r : _routers) {
riSet.addAll(r.getContext().netDb().getRouters());
}
for(Router r : _routers) {
for(RouterInfo ri : riSet){
r.getContext().netDb().publish(ri);
}
}
_out.println(riSet.size() + " RouterInfos were reseeded");
}
private static Properties buildRouterProps(int id) {
Properties props = getRouterProps(id);
File f = new File(props.getProperty("router.configLocation"));
f.getParentFile().mkdirs();
if (!f.exists()) {
try {
DataHelper.storeProps(props, f);
} catch (IOException e) {
e.printStackTrace();
}
}
return props;
}
private static Properties getRouterProps(int id) {
Properties props = new Properties();
FileInputStream in = null;
try {
in = new FileInputStream(filename);
props.load(in);
props.setProperty("time.disabled", "true");
return props;
} catch (IOException ioe) {
ioe.printStackTrace();
return null;
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
props.setProperty("router.profileDir", "/peerProfiles");
props.setProperty("router.sessionKeys.location", "/sessionKeys.dat");
props.setProperty("router.info.location", "/router.info");
props.setProperty("router.keys.location", "/router.keys");
props.setProperty("router.networkDatabase.dbDir", "/netDb");
props.setProperty("router.tunnelPoolFile", "/tunnelPool.dat");
props.setProperty("router.keyBackupDir", "/keyBackup");
props.setProperty("router.clientConfigFile", getBaseDir(id) + "/clients.config");
props.setProperty("router.configLocation", getBaseDir(id) + "/router.config");
props.setProperty("router.pingFile", getBaseDir(id) + "/router.ping");
props.setProperty("router.rejectStartupTime", "0");
props.setProperty("router.reseedDisable", "true");
props.setProperty("i2p.dir.app", getBaseDir(id));
/* If MultiRouter is not run from a dir containing lib/, webapps/, docs/, etc.
* point i2p.dir.base to a directory containing the above. */
//props.setProperty("i2p.dir.base", getBaseDir(id));
props.setProperty("i2p.dir.config", getBaseDir(id));
props.setProperty("i2p.dir.log", getBaseDir(id));
props.setProperty("i2p.dir.router", getBaseDir(id));
props.setProperty("i2p.dir.pid", getBaseDir(id));
//props.setProperty("i2p.vmCommSystem", "true");
props.setProperty("i2np.ntcp.hostname", "127.0.0.1");
props.setProperty("i2np.udp.host", "127.0.0.1");
props.setProperty("i2np.ntcp.port", BASE_PORT + id + "");
props.setProperty("i2np.udp.port", BASE_PORT + id + "");
props.setProperty("i2np.ntcp.allowLocal", "true");
props.setProperty("i2np.udp.allowLocal", "true");
props.setProperty("i2np.udp.internalPort", BASE_PORT + id + "");
props.setProperty("i2cp.port", Integer.toString((BASE_PORT + nbrRouters + id)));
return props;
}
private static Properties buildClientProps(int id) {
Properties rProps = getRouterProps(id);
Properties props = getClientProps();
File f = new File(rProps.getProperty("router.clientConfigFile"));
f.getParentFile().mkdirs();
if (!f.exists()) {
try {
DataHelper.storeProps(props, f);
} catch (IOException e) {
e.printStackTrace();
}
}
return props;
}
private static Properties getClientProps() {
Properties props = new Properties();
props.setProperty("clientApp.0.args", (BASE_PORT-1) + " 127.0.0.1 ./webapps");
props.setProperty("clientApp.0.main", "net.i2p.router.web.RouterConsoleRunner");
props.setProperty("clientApp.0.name", "webconsole");
props.setProperty("clientApp.0.onBoot", "true");
props.setProperty("clientApp.1.args", "i2ptunnel.config");
props.setProperty("clientApp.1.main", "net.i2p.i2ptunnel.TunnelControllerGroup");
props.setProperty("clientApp.1.name", "tunnels");
props.setProperty("clientApp.1.delay", "6");
return props;
}
private static String getBaseDir(int id) {
File f = new File(".");
return f.getAbsoluteFile().getParentFile().toString() + "/multirouter/"+ Integer.toString(id);
}
private static void waitForCompletion() {
......@@ -110,8 +226,7 @@ public class MultiRouter {
for (int i = 0; i < _routers.size(); i++) {
Router r = (Router)_routers.get(i);
if (!r.isAlive()) {
if (_log.shouldLog(Log.INFO))
_log.info("Router " + i + " is dead");
_out.println("Router " + i + " is dead");
} else {
alive++;
}
......@@ -122,13 +237,11 @@ public class MultiRouter {
break;
}
}
_log.info("All routers shut down");
_out.println("All routers shut down");
}
private static void usage() {
System.err.println("Usage: MultiRouter globalContextFile routerContextFile[ routerContextFile]*");
System.err.println(" The context files contain key=value entries specifying properties");
System.err.println(" to load into the given context. In addition, each routerContextFile");
System.err.println(" in turn is used to boot a router");
System.err.println("Usage: MultiRouter nbr_routers");
System.err.println(" Where nbr_routers > 0");
}
}
package net.i2p.router;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Build a set of config files suitable for use by the multirouter as a
* simulation, as well as a pair of scripts for running the simulation.
* Usage: <pre>
* MultiRouterBuilder [routerDir routerPortStart]*
* </pre>
*
* Each router is configured with their own $routerDir/router.config file so
* that all of its data is stored under the $routerDir (profiles, keys, netDb,
* etc). In addition, each router has the i2cp port set to $routerPortStart+1,
* the admin port set to $routerPortStart+2, and some commented out clientApp
* lines (configured with the SAM bridge at $routerPortStart+3 and an EepProxy at
* $routerPortStart+4).<p />
*
* It then builds a $routerDir/heartbeat.config containing the following lines:<ul>
* <li>i2cpHost=localhost</li>
* <li>i2cpPort=$routerPortStart+1</li>
* <li>numHops=2</li>
* <li>privateDestinationFile=$routerDir/heartbeat.keys</li>
* <li>publicDestinationFile=$routerDir/heartbeat.txt</li>
* </ul>
*
* Then it goes on to create the $routerDir/routerEnv.txt:<ul>
* <li>loggerFilenameOverride=$routerDir/logs/log-router-#.txt</li>
* <li>router.configLocation=$routerDir/router.config</li>
* <li>i2p.vmCommSystem=true</li>
* <li>i2p.encryption=off</li>
* </ul>
*
* In addition, it creates a baseEnv.txt: <ul>
* <li>loggerFilenameOverride=logs/log-base-#.txt</li>
* </ul>
*
* Finally, it creates the MultiRouter startup script to launch all of these
* routers, stored at runNetSim.bat / runNetSim.sh
*
*/
public class MultiRouterBuilder {
public static void main(String args[]) {
if (args.length < 2) {
usage();
return;
}
for (int i = 0; i < args.length; i += 2) {
String dir = args[i];
try {
int basePortNum = Integer.parseInt(args[i+1]);
buildConfig(dir, basePortNum, i == 0);
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
}
buildBaseEnv();
buildStartupScript(args);
}
private static void buildBaseEnv() {
File envFile = new File("baseEnv.txt");
try {
FileOutputStream fos = new FileOutputStream(envFile);
fos.write(("loggerFilenameOverride=logs/log-base-#.txt\n").getBytes());
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
File f = new File("logs");
f.mkdirs();
}
private static void buildStartupScript(String args[]) {
buildStartupScriptNix(args);
}
private static void buildStartupScriptNix(String args[]) {
StringBuilder buf = new StringBuilder(4096);
buf.append("#!/bin/sh\n");
buf.append("export CP=.; for LIB in lib/* ; do export CP=$CP:$LIB ; done\n");
buf.append("nohup java -cp $CP ");
buf.append(" -Xmx1024m");
buf.append(" -Djava.library.path=.");
buf.append(" -DloggerFilenameOverride=logs/log-sim-#.txt");
buf.append(" -Dorg.mortbay.http.Version.paranoid=true");
buf.append(" -Dorg.mortbay.util.FileResource.checkAliases=false");
buf.append(" -verbose:gc");
buf.append(" net.i2p.router.MultiRouter baseEnv.txt ");
for (int i = 0; i < args.length; i += 2)
buf.append(args[i]).append("/routerEnv.txt ");
buf.append(" > sim.out 2>&1 &\n");
buf.append("echo $! > sim.pid\n");
buf.append("echo \"After all of the routers have started up, you should cross seed them\"\n");
buf.append("echo \"Simply copy */netDb/routerInfo-* to all of the various */netDb/ directories\"\n");
try {
FileOutputStream fos = new FileOutputStream("runNetSim.sh");
fos.write(buf.toString().getBytes());
fos.close();
} catch (IOException ioe) { ioe.printStackTrace(); }
}
private static void buildConfig(String dir, int basePort, boolean isFirst) {
File baseDir = new File(dir);
baseDir.mkdirs();
File cfgFile = new File(baseDir, "router.config");
StringBuilder buf = new StringBuilder(8*1024);
buf.append("router.profileDir=").append(baseDir.getPath()).append("/peerProfiles\n");
buf.append("router.historyFilename=").append(baseDir.getPath()).append("/messageHistory.txt\n");
buf.append("router.sessionKeys.location=").append(baseDir.getPath()).append("/sessionKeys.dat\n");
buf.append("router.info.location=").append(baseDir.getPath()).append("/router.info\n");
buf.append("router.keys.location=").append(baseDir.getPath()).append("/router.keys\n");
buf.append("router.networkDatabase.dbDir=").append(baseDir.getPath()).append("/netDb\n");
buf.append("router.tunnelPoolFile=").append(baseDir.getPath()).append("/tunnelPool.dat\n");
buf.append("router.keyBackupDir=").append(baseDir.getPath()).append("/keyBackup\n");
buf.append("router.clientConfigFile=").append(baseDir.getPath()).append("/clients.config\n");
buf.append("i2np.tcp.port=").append(basePort).append('\n');
buf.append("i2np.tcp.hostname=localhost\n");
buf.append("i2np.tcp.allowLocal=true\n");
buf.append("i2np.tcp.disable=true\n");
buf.append("i2np.tcp.enable=false\n");
buf.append("i2np.udp.host=127.0.0.1\n");
buf.append("i2np.udp.port=").append(basePort).append('\n');
buf.append("i2np.udp.internalPort=").append(basePort).append('\n');
buf.append("i2cp.port=").append(basePort+1).append('\n');
buf.append("stat.logFile=").append(baseDir.getPath()).append("/stats.log\n");
buf.append("stat.logFilters=*\n");
try {
FileOutputStream fos = new FileOutputStream(cfgFile);
fos.write(buf.toString().getBytes());
fos.close();
File envFile = new File(baseDir, "routerEnv.txt");
fos = new FileOutputStream(envFile);
fos.write(("loggerFilenameOverride="+baseDir+ "/logs/log-router-#.txt\n").getBytes());
fos.write(("router.configLocation="+baseDir+"/router.config\n").getBytes());
fos.write(("router.pingFile="+baseDir+"/router.ping\n").getBytes());
//fos.write(("i2p.vmCommSystem=true\n").getBytes());
//fos.write(("i2p.encryption=off\n").getBytes());
fos.close();
File f = new File(baseDir, "logs");
f.mkdirs();
if (isFirst) {
fos = new FileOutputStream(baseDir.getPath() + "/clients.config");
fos.write(("clientApp.0.args=" + (basePort-1) + " 127.0.0.1 ./webapps\n").getBytes());
fos.write(("clientApp.0.main=net.i2p.router.web.RouterConsoleRunner\n").getBytes());
fos.write(("clientApp.0.name=webconsole\n").getBytes());
fos.write(("clientApp.0.onBoot=true\n").getBytes());
fos.write(("clientApp.1.args=\n").getBytes());
fos.write(("clientApp.1.main=net.i2p.router.Counter\n").getBytes());
fos.write(("clientApp.1.name=counter\n").getBytes());
fos.write(("clientApp.1.onBoot=true\n").getBytes());
fos.write(("clientApp.2.args=i2ptunnel.config\n").getBytes());
fos.write(("clientApp.2.main=net.i2p.i2ptunnel.TunnelControllerGroup\n").getBytes());
fos.write(("clientApp.2.name=tunnels\n").getBytes());
fos.write(("clientApp.2.delay=60\n").getBytes());
fos.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private static void usage() {
System.err.println("Usage: MultiRouterBuilder [routerDir routerPortStart]*");
}
}
......@@ -27,6 +27,8 @@ class RouterThrottleImpl implements RouterThrottle {
private static final String PROP_MAX_TUNNELS = "router.maxParticipatingTunnels";
private static final int DEFAULT_MAX_TUNNELS = 5000;
private static final String PROP_MAX_PROCESSINGTIME = "router.defaultProcessingTimeThrottle";
private static final long DEFAULT_REJECT_STARTUP_TIME = 20*60*1000;
private static final String PROP_REJECT_STARTUP_TIME = "router.rejectStartupTime";
/**
* TO BE FIXED - SEE COMMENTS BELOW
......@@ -39,13 +41,12 @@ class RouterThrottleImpl implements RouterThrottle {
/** = TrivialPreprocessor.PREPROCESSED_SIZE */
private static final int PREPROCESSED_SIZE = 1024;
private static final long REJECT_STARTUP_TIME = 20*60*1000;
public RouterThrottleImpl(RouterContext context) {
_context = context;
_log = context.logManager().getLog(RouterThrottleImpl.class);
setTunnelStatus();
_context.simpleScheduler().addEvent(new ResetStatus(), REJECT_STARTUP_TIME + 120*1000);
_context.simpleScheduler().addEvent(new ResetStatus(), 5*1000 + _context.getProperty(PROP_REJECT_STARTUP_TIME, DEFAULT_REJECT_STARTUP_TIME));
_context.statManager().createRateStat("router.throttleNetworkCause", "How lagged the jobQueue was when an I2NP was throttled", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
//_context.statManager().createRateStat("router.throttleNetDbCause", "How lagged the jobQueue was when a networkDb request was throttled", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
//_context.statManager().createRateStat("router.throttleTunnelCause", "How lagged the jobQueue was when a tunnel request was throttled", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
......@@ -114,7 +115,7 @@ class RouterThrottleImpl implements RouterThrottle {
}
// Don't use CRIT because we don't want peers to think we're failing
if (_context.router().getUptime() < REJECT_STARTUP_TIME) {
if (_context.router().getUptime() < DEFAULT_REJECT_STARTUP_TIME) {
setTunnelStatus(_x("Rejecting tunnels: Starting up"));
return TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment