forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.test' (head be1a2452acf68a8a0137f98f5aeb797055321d6e)
to branch 'i2p.i2p' (head bd6b02d1ae8a99afcea7fdffedf699a6e5c85fbf)
This commit is contained in:
@ -1,8 +1,7 @@
|
||||
$Id: install-headless.txt,v 1.5 2005/09/29 14:19:23 jrandom Exp $
|
||||
Headless I2P installation instructions
|
||||
|
||||
1) tar xjf i2p.tar.bz2 (you've already done this)
|
||||
2) cd i2p ; vi install-headless.txt (you're doing this now)
|
||||
2) cd i2p ; vi INSTALL-headless.txt (you're doing this now)
|
||||
3) sh postinstall.sh (this launches the router)
|
||||
4) lynx http://localhost:7657/index.jsp (configure the router)
|
||||
|
@ -75,7 +75,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
private static long __tunnelId = 0;
|
||||
private long _tunnelId;
|
||||
private Properties _clientOptions;
|
||||
private final List _sessions;
|
||||
private final List<I2PSession> _sessions;
|
||||
|
||||
public static final int PACKET_DELAY = 100;
|
||||
|
||||
@ -179,7 +179,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
List getSessions() {
|
||||
List<I2PSession> getSessions() {
|
||||
synchronized (_sessions) {
|
||||
return new ArrayList(_sessions);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
protected final Object sockLock = new Object(); // Guards sockMgr and mySockets
|
||||
protected I2PSocketManager sockMgr; // should be final and use a factory. LINT
|
||||
protected List mySockets = new ArrayList();
|
||||
protected boolean _ownDest;
|
||||
|
||||
protected Destination dest = null;
|
||||
private int localPort;
|
||||
@ -114,6 +115,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
this.l = l;
|
||||
this.handlerName = handlerName + _clientId;
|
||||
this.privKeyFile = pkf;
|
||||
_ownDest = ownDest; // == ! shared client
|
||||
|
||||
|
||||
_context = tunnel.getContext();
|
||||
@ -129,13 +131,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
boolean openNow = !Boolean.valueOf(tunnel.getClientOptions().getProperty("i2cp.delayOpen")).booleanValue();
|
||||
if (openNow) {
|
||||
while (sockMgr == null) {
|
||||
synchronized (sockLock) {
|
||||
if (ownDest) {
|
||||
sockMgr = buildSocketManager();
|
||||
} else {
|
||||
sockMgr = getSocketManager();
|
||||
}
|
||||
}
|
||||
verifySocketManager();
|
||||
if (sockMgr == null) {
|
||||
_log.log(Log.CRIT, "Unable to create socket manager (our own? " + ownDest + ")");
|
||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
@ -209,27 +205,67 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the this.sockMgr field if it is null, or if we want a new one
|
||||
*
|
||||
* We need a socket manager before getDefaultOptions() and most other things
|
||||
*/
|
||||
protected void verifySocketManager() {
|
||||
synchronized(sockLock) {
|
||||
boolean newManager = false;
|
||||
if (this.sockMgr == null) {
|
||||
newManager = true;
|
||||
} else {
|
||||
I2PSession sess = sockMgr.getSession();
|
||||
if (sess == null) {
|
||||
newManager = true;
|
||||
} else if (sess.isClosed() &&
|
||||
Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.closeOnIdle")).booleanValue() &&
|
||||
Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.newDestOnResume")).booleanValue()) {
|
||||
// build a new socket manager and a new dest if the session is closed.
|
||||
getTunnel().removeSession(sess);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getTunnel().getClientOptions().getProperty("inbound.nickname") + ": Built a new destination on resume");
|
||||
newManager = true;
|
||||
} // else the old socket manager will reconnect the old session if necessary
|
||||
}
|
||||
if (newManager) {
|
||||
if (_ownDest)
|
||||
this.sockMgr = buildSocketManager();
|
||||
else
|
||||
this.sockMgr = getSocketManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** this is ONLY for shared clients */
|
||||
private static I2PSocketManager socketManager;
|
||||
|
||||
/** this is ONLY for shared clients */
|
||||
protected synchronized I2PSocketManager getSocketManager() {
|
||||
return getSocketManager(getTunnel(), this.privKeyFile);
|
||||
}
|
||||
/** this is ONLY for shared clients */
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
|
||||
return getSocketManager(tunnel, null);
|
||||
}
|
||||
/** this is ONLY for shared clients */
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel, String pkf) {
|
||||
if (socketManager != null) {
|
||||
I2PSession s = socketManager.getSession();
|
||||
if ( (s == null) || (s.isClosed()) ) {
|
||||
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Building a new socket manager since the old one closed [s=" + s + "]");
|
||||
if (s != null)
|
||||
tunnel.removeSession(s);
|
||||
socketManager = buildSocketManager(tunnel, pkf);
|
||||
} else {
|
||||
_log.info("Not building a new socket manager since the old one is open [s=" + s + "]");
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Not building a new socket manager since the old one is open [s=" + s + "]");
|
||||
}
|
||||
} else {
|
||||
_log.info("Building a new socket manager since there is no other one");
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Building a new socket manager since there is no other one");
|
||||
socketManager = buildSocketManager(tunnel, pkf);
|
||||
}
|
||||
return socketManager;
|
||||
@ -278,6 +314,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
}
|
||||
sockManager.setName("Client");
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Built a new socket manager [s=" + sockManager.getSession() + "]");
|
||||
tunnel.addSession(sockManager.getSession());
|
||||
return sockManager;
|
||||
}
|
||||
@ -343,12 +381,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
* @return a new I2PSocket
|
||||
*/
|
||||
public I2PSocket createI2PSocket(Destination dest) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException {
|
||||
if (sockMgr == null) {
|
||||
// we need this before getDefaultOptions()
|
||||
synchronized(sockLock) {
|
||||
sockMgr = getSocketManager();
|
||||
}
|
||||
}
|
||||
verifySocketManager();
|
||||
return createI2PSocket(dest, getDefaultOptions());
|
||||
}
|
||||
|
||||
@ -369,22 +402,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
public I2PSocket createI2PSocket(Destination dest, I2PSocketOptions opt) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException {
|
||||
I2PSocket i2ps;
|
||||
|
||||
if (sockMgr == null) {
|
||||
// delayed open - call get instead of build because the locking is up there
|
||||
synchronized(sockLock) {
|
||||
sockMgr = getSocketManager();
|
||||
}
|
||||
} else if (Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.closeOnIdle")).booleanValue() &&
|
||||
Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.newDestOnResume")).booleanValue()) {
|
||||
synchronized(sockLock) {
|
||||
I2PSocketManager oldSockMgr = sockMgr;
|
||||
// This will build a new socket manager and a new dest if the session is closed.
|
||||
sockMgr = getSocketManager();
|
||||
if (oldSockMgr != sockMgr) {
|
||||
_log.warn("Built a new destination on resume");
|
||||
}
|
||||
}
|
||||
} // else the old socket manager will reconnect the old session if necessary
|
||||
verifySocketManager();
|
||||
i2ps = sockMgr.connect(dest, opt);
|
||||
synchronized (sockLock) {
|
||||
mySockets.add(i2ps);
|
||||
|
@ -157,11 +157,7 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna
|
||||
if (!defaultOpts.contains("i2p.streaming.inactivityTimeout"))
|
||||
defaultOpts.setProperty("i2p.streaming.inactivityTimeout", ""+DEFAULT_READ_TIMEOUT);
|
||||
// delayed start
|
||||
if (sockMgr == null) {
|
||||
synchronized(sockLock) {
|
||||
sockMgr = getSocketManager();
|
||||
}
|
||||
}
|
||||
verifySocketManager();
|
||||
I2PSocketOptions opts = sockMgr.buildOptions(defaultOpts);
|
||||
if (!defaultOpts.containsKey(I2PSocketOptions.PROP_CONNECT_TIMEOUT))
|
||||
opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
|
||||
|
@ -211,11 +211,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
if (!defaultOpts.contains("i2p.streaming.inactivityTimeout"))
|
||||
defaultOpts.setProperty("i2p.streaming.inactivityTimeout", ""+DEFAULT_READ_TIMEOUT);
|
||||
// delayed start
|
||||
if (sockMgr == null) {
|
||||
synchronized(sockLock) {
|
||||
sockMgr = getSocketManager();
|
||||
}
|
||||
}
|
||||
verifySocketManager();
|
||||
I2PSocketOptions opts = sockMgr.buildOptions(defaultOpts);
|
||||
if (!defaultOpts.containsKey(I2PSocketOptions.PROP_CONNECT_TIMEOUT))
|
||||
opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
|
||||
|
@ -434,6 +434,16 @@ public class TunnelController implements Logging {
|
||||
|
||||
public boolean getIsRunning() { return _running; }
|
||||
public boolean getIsStarting() { return _starting; }
|
||||
/** if running but no open sessions, we are in standby */
|
||||
public boolean getIsStandby() {
|
||||
if (!_running)
|
||||
return false;
|
||||
for (I2PSession sess : _tunnel.getSessions()) {
|
||||
if (!sess.isClosed())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void getSummary(StringBuffer buf) {
|
||||
String type = getType();
|
||||
|
@ -77,6 +77,7 @@ public class IndexBean {
|
||||
public static final int RUNNING = 1;
|
||||
public static final int STARTING = 2;
|
||||
public static final int NOT_RUNNING = 3;
|
||||
public static final int STANDBY = 4;
|
||||
|
||||
public static final String PROP_TUNNEL_PASSPHRASE = "i2ptunnel.passphrase";
|
||||
static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
|
||||
@ -412,8 +413,12 @@ public class IndexBean {
|
||||
public int getTunnelStatus(int tunnel) {
|
||||
TunnelController tun = getController(tunnel);
|
||||
if (tun == null) return NOT_RUNNING;
|
||||
if (tun.getIsRunning()) return RUNNING;
|
||||
else if (tun.getIsStarting()) return STARTING;
|
||||
if (tun.getIsRunning()) {
|
||||
if (isClient(tunnel) && tun.getIsStandby())
|
||||
return STANDBY;
|
||||
else
|
||||
return RUNNING;
|
||||
} else if (tun.getIsStarting()) return STARTING;
|
||||
else return NOT_RUNNING;
|
||||
}
|
||||
|
||||
@ -778,12 +783,6 @@ public class IndexBean {
|
||||
config.setProperty("interface", _reachableByOther);
|
||||
else
|
||||
config.setProperty("interface", _reachableBy);
|
||||
config.setProperty("option.inbound.nickname", CLIENT_NICKNAME);
|
||||
config.setProperty("option.outbound.nickname", CLIENT_NICKNAME);
|
||||
if (_name != null && !_sharedClient) {
|
||||
config.setProperty("option.inbound.nickname", _name);
|
||||
config.setProperty("option.outbound.nickname", _name);
|
||||
}
|
||||
config.setProperty("sharedClient", _sharedClient + "");
|
||||
for (String p : _booleanClientOpts)
|
||||
config.setProperty("option." + p, "" + _booleanOptions.contains(p));
|
||||
@ -896,14 +895,12 @@ public class IndexBean {
|
||||
config.setProperty("option.i2p.streaming.connectDelay", "1000");
|
||||
else
|
||||
config.setProperty("option.i2p.streaming.connectDelay", "0");
|
||||
if (_name != null) {
|
||||
if ( (!isClient(_type)) || (!_sharedClient) ) {
|
||||
config.setProperty("option.inbound.nickname", _name);
|
||||
config.setProperty("option.outbound.nickname", _name);
|
||||
} else {
|
||||
config.setProperty("option.inbound.nickname", CLIENT_NICKNAME);
|
||||
config.setProperty("option.outbound.nickname", CLIENT_NICKNAME);
|
||||
}
|
||||
if (isClient(_type) && _sharedClient) {
|
||||
config.setProperty("option.inbound.nickname", CLIENT_NICKNAME);
|
||||
config.setProperty("option.outbound.nickname", CLIENT_NICKNAME);
|
||||
} else if (_name != null) {
|
||||
config.setProperty("option.inbound.nickname", _name);
|
||||
config.setProperty("option.outbound.nickname", _name);
|
||||
}
|
||||
if ("interactive".equals(_profile))
|
||||
// This was 1 which doesn't make much sense
|
||||
|
@ -97,6 +97,11 @@
|
||||
case IndexBean.STARTING:
|
||||
%><div class="statusStarting text">Starting...</div>
|
||||
<a class="control" title="Stop this Tunnel" href="index.jsp?nonce=<%=indexBean.getNextNonce()%>&action=stop&tunnel=<%=curClient%>">Stop</a>
|
||||
<%
|
||||
break;
|
||||
case IndexBean.STANDBY:
|
||||
%><div class="statusStarting text">Standby</div>
|
||||
<a class="control" title="Stop this Tunnel" href="index.jsp?nonce=<%=indexBean.getNextNonce()%>&action=stop&tunnel=<%=curClient%>">Stop</a>
|
||||
<%
|
||||
break;
|
||||
case IndexBean.RUNNING:
|
||||
|
@ -91,8 +91,9 @@ public class ReseedHandler {
|
||||
public boolean isRunning() { return _isRunning; }
|
||||
public void run() {
|
||||
_isRunning = true;
|
||||
System.out.println("Reseed start");
|
||||
reseed(false);
|
||||
System.out.println("Reseeding complete");
|
||||
System.out.println("Reseed complete");
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.reseedInProgress", "false");
|
||||
_isRunning = false;
|
||||
}
|
||||
@ -133,7 +134,7 @@ public class ReseedHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a directory listing and then all the routerInfo files in the listing.
|
||||
* Fetch a directory listing and then up to 200 routerInfo files in the listing.
|
||||
* The listing must contain (exactly) strings that match:
|
||||
* href="routerInfo-{hash}.dat">
|
||||
* and then it fetches the files
|
||||
@ -147,6 +148,7 @@ public class ReseedHandler {
|
||||
try {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.statusMessage","Reseeding: fetching seed URL.");
|
||||
System.err.println("Reseed from " + seedURL);
|
||||
URL dir = new URL(seedURL);
|
||||
byte contentRaw[] = readURL(dir);
|
||||
if (contentRaw == null) {
|
||||
@ -160,7 +162,8 @@ public class ReseedHandler {
|
||||
String content = new String(contentRaw);
|
||||
Set urls = new HashSet();
|
||||
int cur = 0;
|
||||
while (true) {
|
||||
int total = 0;
|
||||
while (total++ < 1000) {
|
||||
int start = content.indexOf("href=\"routerInfo-", cur);
|
||||
if (start < 0)
|
||||
break;
|
||||
@ -170,7 +173,7 @@ public class ReseedHandler {
|
||||
urls.add(name);
|
||||
cur = end + 1;
|
||||
}
|
||||
if (urls.size() <= 0) {
|
||||
if (total <= 0) {
|
||||
_log.error("Read " + contentRaw.length + " bytes from seed " + seedURL + ", but found no routerInfo URLs.");
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed fully (no routerInfo URLs at seed URL). " +
|
||||
@ -178,13 +181,16 @@ public class ReseedHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
List urlList = new ArrayList(urls);
|
||||
Collections.shuffle(urlList);
|
||||
int fetched = 0;
|
||||
int errors = 0;
|
||||
for (Iterator iter = urls.iterator(); iter.hasNext(); ) {
|
||||
// 200 max from one URL
|
||||
for (Iterator iter = urlList.iterator(); iter.hasNext() && fetched < 200; ) {
|
||||
try {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.statusMessage",
|
||||
"Reseeding: fetching router info from seed URL (" +
|
||||
fetched + " successful, " + errors + " errors, " + urls.size() + " total).");
|
||||
fetched + " successful, " + errors + " errors, " + total + " total).");
|
||||
|
||||
fetchSeed(seedURL, (String)iter.next());
|
||||
fetched++;
|
||||
@ -197,24 +203,24 @@ public class ReseedHandler {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (echoStatus) System.out.println();
|
||||
System.err.println("Reseed got " + fetched + " router infos from " + seedURL);
|
||||
|
||||
int failPercent = 100 * errors / urls.size();
|
||||
int failPercent = 100 * errors / total;
|
||||
|
||||
// Less than 10% of failures is considered success,
|
||||
// because some routerInfos will always fail.
|
||||
if ((failPercent >= 10) && (failPercent < 90)) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed partly (" + failPercent + "% of " + urls.size() + "). " +
|
||||
"Last reseed failed partly (" + failPercent + "% of " + total + "). " +
|
||||
RESEED_TIPS);
|
||||
}
|
||||
if (failPercent >= 90) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed (" + failPercent + "% of " + urls.size() + "). " +
|
||||
"Last reseed failed (" + failPercent + "% of " + total + "). " +
|
||||
RESEED_TIPS);
|
||||
}
|
||||
// Don't go on to the next URL if we have enough
|
||||
if (fetched > 25)
|
||||
if (fetched >= 100)
|
||||
_isRunning = false;
|
||||
} catch (Throwable t) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
|
@ -32,6 +32,7 @@
|
||||
<input type="submit" name="action" value="Shutdown immediately" />
|
||||
<input type="submit" name="action" value="Cancel graceful shutdown" />
|
||||
|
||||
<% if (System.getProperty("wrapper.version") != null) { %>
|
||||
<p>If you want the router to restart itself after shutting down, you can choose one of
|
||||
the following. This is useful in some situations - for example, if you changed
|
||||
some settings that client applications only read at startup, such as the routerconsole password
|
||||
@ -41,6 +42,7 @@
|
||||
|
||||
<input type="submit" name="action" value="Graceful restart" />
|
||||
<input type="submit" name="action" value="Hard restart" />
|
||||
<% } %>
|
||||
|
||||
<% if ( (System.getProperty("os.name") != null) && (System.getProperty("os.name").startsWith("Win")) ) { %>
|
||||
<h4>Systray integration</h4>
|
||||
@ -61,11 +63,14 @@
|
||||
down your router immediately. You may want to consider shutting down gracefully, as
|
||||
above, then running uninstall_i2p_service_winnt.bat.</p>
|
||||
<% } %>
|
||||
|
||||
<% if (System.getProperty("wrapper.version") != null) { %>
|
||||
<h4>Debugging</h4>
|
||||
<p>At times, it may be helpful to debug I2P by getting a thread dump. To do so,
|
||||
please select the following option and review the thread dumped to
|
||||
<a href="logs.jsp#servicelogs">wrapper.log</a>.</p>
|
||||
<input type="submit" name="action" value="Dump threads" />
|
||||
<% } %>
|
||||
|
||||
<h4>Launch browser on router startup?</h4>
|
||||
<p>I2P's main configuration interface is this web console, so for your convenience
|
||||
|
@ -278,7 +278,7 @@
|
||||
<fileset dir="installer/lib/wrapper/win32/" />
|
||||
</copy>
|
||||
<copy file="hosts.txt" todir="pkg-temp/" />
|
||||
<copy file="install-headless.txt" todir="pkg-temp/" />
|
||||
<copy file="INSTALL-headless.txt" todir="pkg-temp/" />
|
||||
<copy file="history.txt" todir="pkg-temp/" />
|
||||
<mkdir dir="pkg-temp/scripts" />
|
||||
<copy file="apps/proxyscript/i2pProxy.pac" todir="pkg-temp/scripts/" />
|
||||
|
@ -18,6 +18,10 @@ Review the complete diff from the last release:
|
||||
mtn diff -r t:i2p-0.7.(xx-1) > out.diff
|
||||
vi out.diff
|
||||
|
||||
Verify that no untrusted revisions were inadvertently
|
||||
blessed by a trusted party:
|
||||
mtn log --brief --no-graph --to t:i2p-0.7.(xx-1) | cut -d ' ' -f 2- | sort
|
||||
|
||||
Build and tag:
|
||||
ant pkg
|
||||
mtn ci
|
||||
|
@ -49,11 +49,15 @@ class RouterWatchdog implements Runnable {
|
||||
}
|
||||
|
||||
private boolean shutdownOnHang() {
|
||||
// prop default true
|
||||
if (!Boolean.valueOf(_context.getProperty("watchdog.haltOnHang", "true")).booleanValue())
|
||||
return false;
|
||||
|
||||
// Client manager starts complaining after 10 minutes, and we run every minute,
|
||||
// so this will restart 20 minutes after we lose a lease, if the wrapper is present.
|
||||
if (_consecutiveErrors >= 10 && System.getProperty("wrapper.version") != null)
|
||||
// so this will restart 30 minutes after we lose a lease, if the wrapper is present.
|
||||
if (_consecutiveErrors >= 20 && System.getProperty("wrapper.version") != null)
|
||||
return true;
|
||||
return Boolean.valueOf(_context.getProperty("watchdog.haltOnHang", "false")).booleanValue();
|
||||
return false;
|
||||
}
|
||||
|
||||
private void dumpStatus() {
|
||||
@ -90,13 +94,14 @@ class RouterWatchdog implements Runnable {
|
||||
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||
_log.error("Memory: " + DataHelper.formatSize(used) + '/' + DataHelper.formatSize(max));
|
||||
if (_consecutiveErrors == 1) {
|
||||
_log.log(Log.CRIT, "Router appears hung! Will restart in 20 minutes if it doesn't fix itself");
|
||||
// This might work on linux...
|
||||
// It won't on windows, and we can't call i2prouter.bat either, it does something
|
||||
// completely different...
|
||||
ShellCommand sc = new ShellCommand();
|
||||
boolean success = sc.executeSilentAndWaitTimed("./i2prouter dump", 10);
|
||||
if (success)
|
||||
_log.error("DUMPED THREADS TO WRAPPER LOG");
|
||||
_log.log(Log.CRIT, "Threads dumped to wrapper log");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,7 +132,7 @@ class RouterWatchdog implements Runnable {
|
||||
_consecutiveErrors++;
|
||||
dumpStatus();
|
||||
if (shutdownOnHang()) {
|
||||
_log.log(Log.CRIT, "Router hung! hard restart!");
|
||||
_log.log(Log.CRIT, "Router hung! Restart forced by watchdog!");
|
||||
try { Thread.sleep(30*1000); } catch (InterruptedException ie) {}
|
||||
// halt and not system.exit, since some of the shutdown hooks might be misbehaving
|
||||
Runtime.getRuntime().halt(Router.EXIT_HARD_RESTART);
|
||||
|
@ -87,9 +87,14 @@ public class StatisticsManager implements Service {
|
||||
|
||||
if (_includePeerRankings) {
|
||||
long publishedUptime = _context.router().getUptime();
|
||||
boolean commentOutIn074 = RouterVersion.VERSION.equals("0.7.3");
|
||||
// Don't publish these for first hour
|
||||
if (publishedUptime > 60*60*1000)
|
||||
includeThroughput(stats);
|
||||
if (publishedUptime > 62*60*1000) {
|
||||
if (commentOutIn074)
|
||||
includeThroughput(stats);
|
||||
else
|
||||
includeAverageThroughput(stats);
|
||||
}
|
||||
//includeRate("router.invalidMessageTime", stats, new long[] { 10*60*1000 });
|
||||
//includeRate("router.duplicateMessageId", stats, new long[] { 24*60*60*1000 });
|
||||
//includeRate("tunnel.duplicateIV", stats, new long[] { 24*60*60*1000 });
|
||||
@ -223,16 +228,26 @@ public class StatisticsManager implements Service {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/* report the same data for tx and rx, for enhanced anonymity */
|
||||
private void includeAverageThroughput(Properties stats) {
|
||||
RateStat sendRate = _context.statManager().getRate("bw.sendRate");
|
||||
RateStat recvRate = _context.statManager().getRate("bw.recvRate");
|
||||
if (sendRate == null || recvRate == null)
|
||||
return;
|
||||
Rate s = sendRate.getRate(60*60*1000);
|
||||
Rate r = recvRate.getRate(60*60*1000);
|
||||
if (s == null || r == null)
|
||||
return;
|
||||
double speed = (s.getAverageValue() + r.getAverageValue()) / 2;
|
||||
double max = Math.max(s.getExtremeAverageValue(), r.getExtremeAverageValue());
|
||||
String str = num(speed) + ';' + num(max) + ";0;0;";
|
||||
stats.setProperty("stat_bandwidthSendBps.60m", str);
|
||||
stats.setProperty("stat_bandwidthReceiveBps.60m", str);
|
||||
}
|
||||
|
||||
private void includeThroughput(Properties stats) {
|
||||
RateStat sendRate = _context.statManager().getRate("bw.sendRate");
|
||||
if (sendRate != null) {
|
||||
/****
|
||||
if (_context.router().getUptime() > 5*60*1000) {
|
||||
Rate r = sendRate.getRate(5*60*1000);
|
||||
if (r != null)
|
||||
stats.setProperty("stat_bandwidthSendBps.5m", num(r.getAverageValue()) + ';' + num(r.getExtremeAverageValue()) + ";0;0;");
|
||||
}
|
||||
****/
|
||||
if (_context.router().getUptime() > 60*60*1000) {
|
||||
Rate r = sendRate.getRate(60*60*1000);
|
||||
if (r != null)
|
||||
@ -242,13 +257,6 @@ public class StatisticsManager implements Service {
|
||||
|
||||
RateStat recvRate = _context.statManager().getRate("bw.recvRate");
|
||||
if (recvRate != null) {
|
||||
/****
|
||||
if (_context.router().getUptime() > 5*60*1000) {
|
||||
Rate r = recvRate.getRate(5*60*1000);
|
||||
if (r != null)
|
||||
stats.setProperty("stat_bandwidthReceiveBps.5m", num(r.getAverageValue()) + ';' + num(r.getExtremeAverageValue()) + ";0;0;");
|
||||
}
|
||||
****/
|
||||
if (_context.router().getUptime() > 60*60*1000) {
|
||||
Rate r = recvRate.getRate(60*60*1000);
|
||||
if (r != null)
|
||||
|
@ -100,8 +100,10 @@ class FloodOnlySearchJob extends FloodSearchJob {
|
||||
if (floodfillPeers.size() <= 3)
|
||||
_shouldProcessDSRM = true;
|
||||
if (floodfillPeers.size() <= 0) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Running netDb searches against the floodfill peers, but we don't know any");
|
||||
// ask anybody, they may not return the answer but they will return a few ff peers we can go look up,
|
||||
// so this situation should be temporary
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Running netDb searches against the floodfill peers, but we don't know any");
|
||||
floodfillPeers = new ArrayList(_facade.getAllRouters());
|
||||
if (floodfillPeers.size() <= 0) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
|
@ -8,6 +8,12 @@ import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Ask the peer who sent us the DSRM for the RouterInfos.
|
||||
*
|
||||
* If we have the routerInfo already, try to refetch it from that router itself,
|
||||
* if we aren't already connected to that router,
|
||||
* which will help us establish that router as a good floodfill and speed our
|
||||
* integration into the network.
|
||||
*
|
||||
* A simple version of SearchReplyJob in SearchJob.java.
|
||||
* Skip the profile updates - this should be rare.
|
||||
*
|
||||
@ -28,6 +34,8 @@ class SingleLookupJob extends JobImpl {
|
||||
continue;
|
||||
if (getContext().netDb().lookupRouterInfoLocally(peer) == null)
|
||||
getContext().jobQueue().addJob(new SingleSearchJob(getContext(), peer, from));
|
||||
else if (!getContext().commSystem().isEstablished(peer))
|
||||
getContext().jobQueue().addJob(new SingleSearchJob(getContext(), peer, peer));
|
||||
}
|
||||
}
|
||||
public String getName() { return "NetDb process DSRM"; }
|
||||
|
@ -34,8 +34,14 @@ public class FIFOBandwidthRefiller implements Runnable {
|
||||
//public static final String PROP_REPLENISH_FREQUENCY = "i2np.bandwidth.replenishFrequencyMs";
|
||||
|
||||
// no longer allow unlimited bandwidth - the user must specify a value, else use defaults below (KBps)
|
||||
public static final int DEFAULT_INBOUND_BANDWIDTH = 64;
|
||||
public static final int DEFAULT_OUTBOUND_BANDWIDTH = 32;
|
||||
public static final int DEFAULT_INBOUND_BANDWIDTH = 96;
|
||||
/**
|
||||
* Caution, do not make DEFAULT_OUTBOUND_BANDWIDTH * DEFAULT_SHARE_PCT > 32
|
||||
* without thinking about the implications (default connection limits, for example)
|
||||
* of moving the default bandwidth class from L to M, or maybe
|
||||
* adjusting bandwidth class boundaries.
|
||||
*/
|
||||
public static final int DEFAULT_OUTBOUND_BANDWIDTH = 40;
|
||||
public static final int DEFAULT_INBOUND_BURST_BANDWIDTH = 80;
|
||||
public static final int DEFAULT_OUTBOUND_BURST_BANDWIDTH = 40;
|
||||
|
||||
|
Reference in New Issue
Block a user