* Clock: Cleanups and javadocs

* EepGet: Cleanups and javadocs
    * Reseed: Use the reseeder as a clock source
This commit is contained in:
zzz
2011-02-11 23:59:10 +00:00
parent 3f3385fdde
commit f11a543233
13 changed files with 169 additions and 102 deletions

View File

@ -59,7 +59,6 @@ public class I2PSocketEepGet extends EepGet {
// public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, long minSize, long maxSize, String outputFile, OutputStream outputStream, String url, boolean allowCaching, String etag, String postData) { // public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, long minSize, long maxSize, String outputFile, OutputStream outputStream, String url, boolean allowCaching, String etag, String postData) {
super(ctx, false, null, -1, numRetries, minSize, maxSize, outputFile, outputStream, url, true, null, null); super(ctx, false, null, -1, numRetries, minSize, maxSize, outputFile, outputStream, url, true, null, null);
_socketManager = mgr; _socketManager = mgr;
_log = ctx.logManager().getLog(I2PSocketEepGet.class);
} }
/** /**

View File

@ -3,11 +3,9 @@ package net.i2p.router.web;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.crypto.TrustedUpdate; import net.i2p.crypto.TrustedUpdate;
@ -15,6 +13,7 @@ import net.i2p.data.DataHelper;
import net.i2p.router.Router; import net.i2p.router.Router;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.RouterVersion; import net.i2p.router.RouterVersion;
import net.i2p.router.util.RFC822Date;
import net.i2p.util.EepGet; import net.i2p.util.EepGet;
import net.i2p.util.EepHead; import net.i2p.util.EepHead;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
@ -73,7 +72,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
if (_lastFetch == 0) if (_lastFetch == 0)
_lastFetch = _lastUpdated; _lastFetch = _lastUpdated;
if (_lastModified == null) if (_lastModified == null)
_lastModified = to822Date(_lastFetch); _lastModified = RFC822Date.to822Date(_lastFetch);
} else { } else {
_lastUpdated = 0; _lastUpdated = 0;
_lastFetch = 0; _lastFetch = 0;
@ -212,7 +211,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
String lastmod = get.getLastModified(); String lastmod = get.getLastModified();
if (lastmod != null) { if (lastmod != null) {
if (!(_context.isRouterContext())) return; if (!(_context.isRouterContext())) return;
long modtime = parse822Date(lastmod); long modtime = RFC822Date.parse822Date(lastmod);
if (modtime <= 0) return; if (modtime <= 0) return;
String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME); String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME);
if (lastUpdate == null) { if (lastUpdate == null) {
@ -251,44 +250,6 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
handler.update(); handler.update();
} }
/**
* http://jimyjoshi.com/blog/2007/08/rfc822dateparsinginjava.html
* Apparently public domain
* Probably don't need all of these...
*/
private static final SimpleDateFormat rfc822DateFormats[] = new SimpleDateFormat[] {
new SimpleDateFormat("EEE, d MMM yy HH:mm:ss z", Locale.US),
new SimpleDateFormat("EEE, d MMM yy HH:mm z", Locale.US),
new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US),
new SimpleDateFormat("EEE, d MMM yyyy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yy HH:mm:ss z", Locale.US),
new SimpleDateFormat("d MMM yyyy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US)
};
/**
* new Date(String foo) is deprecated, so let's do this the hard way
*
* @param s non-null
* @return -1 on failure
*/
public static long parse822Date(String s) {
for (int i = 0; i < rfc822DateFormats.length; i++) {
try {
Date date = rfc822DateFormats[i].parse(s);
if (date != null)
return date.getTime();
} catch (ParseException pe) {}
}
return -1;
}
/** @since 0.8.2 */
private static String to822Date(long t) {
return (new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US)).format(new Date(t));
}
private static final String VERSION_STRING = "version=\"" + RouterVersion.VERSION + "\""; private static final String VERSION_STRING = "version=\"" + RouterVersion.VERSION + "\"";
private static final String VERSION_PREFIX = "version=\""; private static final String VERSION_PREFIX = "version=\"";
private void checkForUpdates() { private void checkForUpdates() {

View File

@ -4,6 +4,7 @@ import java.io.File;
import net.i2p.router.Router; import net.i2p.router.Router;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.util.RFC822Date;
import net.i2p.util.EepGet; import net.i2p.util.EepGet;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
import net.i2p.util.I2PAppThread; import net.i2p.util.I2PAppThread;
@ -101,7 +102,7 @@ public class UnsignedUpdateHandler extends UpdateHandler {
String lastmod = _get.getLastModified(); String lastmod = _get.getLastModified();
long modtime = 0; long modtime = 0;
if (lastmod != null) if (lastmod != null)
modtime = NewsFetcher.parse822Date(lastmod); modtime = RFC822Date.parse822Date(lastmod);
if (modtime <= 0) if (modtime <= 0)
modtime = _context.clock().now(); modtime = _context.clock().now();
_context.router().setConfigSetting(PROP_LAST_UPDATE_TIME, "" + modtime); _context.router().setConfigSetting(PROP_LAST_UPDATE_TIME, "" + modtime);

View File

@ -15,6 +15,7 @@ import net.i2p.data.DataHelper;
import net.i2p.router.Router; import net.i2p.router.Router;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.RouterVersion; import net.i2p.router.RouterVersion;
import net.i2p.router.util.RFC822Date;
import net.i2p.util.EepGet; import net.i2p.util.EepGet;
import net.i2p.util.I2PAppThread; import net.i2p.util.I2PAppThread;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -271,7 +272,7 @@ public class UpdateHandler {
String lastmod = _get.getLastModified(); String lastmod = _get.getLastModified();
long modtime = 0; long modtime = 0;
if (lastmod != null) if (lastmod != null)
modtime = NewsFetcher.parse822Date(lastmod); modtime = RFC822Date.parse822Date(lastmod);
if (modtime <= 0) if (modtime <= 0)
modtime = _context.clock().now(); modtime = _context.clock().now();
_context.router().setConfigSetting(PROP_LAST_UPDATE_TIME, "" + modtime); _context.router().setConfigSetting(PROP_LAST_UPDATE_TIME, "" + modtime);

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.util.I2PThread; import net.i2p.util.I2PThread;
@ -56,7 +57,7 @@ public class Timestamper implements Runnable {
public Timestamper(I2PAppContext ctx, UpdateListener lsnr, boolean daemon) { public Timestamper(I2PAppContext ctx, UpdateListener lsnr, boolean daemon) {
// moved here to prevent problems with synchronized statements. // moved here to prevent problems with synchronized statements.
_servers = new ArrayList(3); _servers = new ArrayList(3);
_listeners = new ArrayList(1); _listeners = new CopyOnWriteArrayList();
// Don't bother starting a thread if we are disabled. // Don't bother starting a thread if we are disabled.
// This means we no longer check every 5 minutes to see if we got enabled, // This means we no longer check every 5 minutes to see if we got enabled,
// so the property must be set at startup. // so the property must be set at startup.
@ -92,24 +93,16 @@ public class Timestamper implements Runnable {
public boolean getIsDisabled() { return _disabled; } public boolean getIsDisabled() { return _disabled; }
public void addListener(UpdateListener lsnr) { public void addListener(UpdateListener lsnr) {
synchronized (_listeners) {
_listeners.add(lsnr); _listeners.add(lsnr);
}
} }
public void removeListener(UpdateListener lsnr) { public void removeListener(UpdateListener lsnr) {
synchronized (_listeners) {
_listeners.remove(lsnr); _listeners.remove(lsnr);
}
} }
public int getListenerCount() { public int getListenerCount() {
synchronized (_listeners) {
return _listeners.size(); return _listeners.size();
}
} }
public UpdateListener getListener(int index) { public UpdateListener getListener(int index) {
synchronized (_listeners) {
return _listeners.get(index); return _listeners.get(index);
}
} }
private void startTimestamper() { private void startTimestamper() {
@ -257,11 +250,8 @@ public class Timestamper implements Runnable {
*/ */
private void stampTime(long now, int stratum) { private void stampTime(long now, int stratum) {
long before = _context.clock().now(); long before = _context.clock().now();
synchronized (_listeners) { for (UpdateListener lsnr : _listeners) {
for (int i = 0; i < _listeners.size(); i++) { lsnr.setNow(now, stratum);
UpdateListener lsnr = _listeners.get(i);
lsnr.setNow(now, stratum);
}
} }
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamped the time as " + now + " (delta=" + (now-before) + ")"); _log.debug("Stamped the time as " + now + " (delta=" + (now-before) + ")");

View File

@ -49,14 +49,22 @@ public class Clock implements Timestamper.UpdateListener {
/** if the clock skewed changes by less than this, ignore the update (so we don't slide all over the place) */ /** if the clock skewed changes by less than this, ignore the update (so we don't slide all over the place) */
public final static long MIN_OFFSET_CHANGE = 5 * 1000; public final static long MIN_OFFSET_CHANGE = 5 * 1000;
/**
* Specify how far away from the "correct" time the computer is - a positive
* value means that the system time is slow, while a negative value means the system time is fast.
*
* @param offsetMs the delta from System.currentTimeMillis() (NOT the delta from now())
*/
public void setOffset(long offsetMs) { public void setOffset(long offsetMs) {
setOffset(offsetMs, false); setOffset(offsetMs, false);
} }
/** /**
* Specify how far away from the "correct" time the computer is - a positive * Specify how far away from the "correct" time the computer is - a positive
* value means that we are slow, while a negative value means we are fast. * value means that the system time is slow, while a negative value means the system time is fast.
* Warning - overridden in RouterClock * Warning - overridden in RouterClock
*
* @param offsetMs the delta from System.currentTimeMillis() (NOT the delta from now())
*/ */
public void setOffset(long offsetMs, boolean force) { public void setOffset(long offsetMs, boolean force) {
if (false) return; if (false) return;
@ -101,6 +109,9 @@ public class Clock implements Timestamper.UpdateListener {
fireOffsetChanged(delta); fireOffsetChanged(delta);
} }
/*
* @return the current delta from System.currentTimeMillis() in milliseconds
*/
public long getOffset() { public long getOffset() {
return _offset; return _offset;
} }

View File

@ -28,21 +28,21 @@ import net.i2p.util.InternalSocket;
* Bug: a malformed url http://example.i2p (no trailing '/') fails cryptically * Bug: a malformed url http://example.i2p (no trailing '/') fails cryptically
*/ */
public class EepGet { public class EepGet {
protected I2PAppContext _context; protected final I2PAppContext _context;
protected Log _log; protected final Log _log;
protected boolean _shouldProxy; protected final boolean _shouldProxy;
private String _proxyHost; private final String _proxyHost;
private int _proxyPort; private final int _proxyPort;
protected int _numRetries; protected final int _numRetries;
private long _minSize; // minimum and maximum acceptable response size, -1 signifies unlimited, private final long _minSize; // minimum and maximum acceptable response size, -1 signifies unlimited,
private long _maxSize; // applied both against whole responses and chunks private final long _maxSize; // applied both against whole responses and chunks
protected String _outputFile; protected final String _outputFile;
protected OutputStream _outputStream; protected final OutputStream _outputStream;
/** url we were asked to fetch */ /** url we were asked to fetch */
protected String _url; protected final String _url;
/** the URL we actually fetch from (may differ from the _url in case of redirect) */ /** the URL we actually fetch from (may differ from the _url in case of redirect) */
protected String _actualURL; protected String _actualURL;
private String _postData; private final String _postData;
private boolean _allowCaching; private boolean _allowCaching;
protected final List<StatusListener> _listeners; protected final List<StatusListener> _listeners;
@ -106,7 +106,7 @@ public class EepGet {
String outputFile, OutputStream outputStream, String url, boolean allowCaching, String outputFile, OutputStream outputStream, String url, boolean allowCaching,
String etag, String lastModified, String postData) { String etag, String lastModified, String postData) {
_context = ctx; _context = ctx;
_log = ctx.logManager().getLog(EepGet.class); _log = ctx.logManager().getLog(getClass());
_shouldProxy = (proxyHost != null) && (proxyHost.length() > 0) && (proxyPort > 0) && shouldProxy; _shouldProxy = (proxyHost != null) && (proxyHost.length() > 0) && (proxyPort > 0) && shouldProxy;
_proxyHost = proxyHost; _proxyHost = proxyHost;
_proxyPort = proxyPort; _proxyPort = proxyPort;
@ -118,13 +118,7 @@ public class EepGet {
_url = url; _url = url;
_actualURL = url; _actualURL = url;
_postData = postData; _postData = postData;
_alreadyTransferred = 0;
_bytesTransferred = 0;
_bytesRemaining = -1; _bytesRemaining = -1;
_currentAttempt = 0;
_transferFailed = false;
_headersRead = false;
_aborted = false;
_fetchHeaderTimeout = CONNECT_TIMEOUT; _fetchHeaderTimeout = CONNECT_TIMEOUT;
_listeners = new ArrayList(1); _listeners = new ArrayList(1);
_etag = etag; _etag = etag;
@ -255,9 +249,9 @@ public class EepGet {
public void attempting(String url); public void attempting(String url);
} }
protected class CLIStatusListener implements StatusListener { protected class CLIStatusListener implements StatusListener {
private int _markSize; private final int _markSize;
private int _lineSize; private final int _lineSize;
private long _startedOn; private final long _startedOn;
private long _written; private long _written;
private long _previousWritten; private long _previousWritten;
private long _discarded; private long _discarded;
@ -271,9 +265,6 @@ public class EepGet {
public CLIStatusListener(int markSize, int lineSize) { public CLIStatusListener(int markSize, int lineSize) {
_markSize = markSize; _markSize = markSize;
_lineSize = lineSize; _lineSize = lineSize;
_written = 0;
_previousWritten = 0;
_discarded = 0;
_lastComplete = _context.clock().now(); _lastComplete = _context.clock().now();
_startedOn = _lastComplete; _startedOn = _lastComplete;
_firstTime = true; _firstTime = true;

View File

@ -24,7 +24,7 @@ public class RouterClock extends Clock {
* All of this is @since 0.7.12 * All of this is @since 0.7.12
*/ */
private static final long MAX_SLEW = 50; private static final long MAX_SLEW = 50;
private static final int DEFAULT_STRATUM = 8; public static final int DEFAULT_STRATUM = 8;
private static final int WORST_STRATUM = 16; private static final int WORST_STRATUM = 16;
/** the max NTP Timestamper delay is 30m right now, make this longer than that */ /** the max NTP Timestamper delay is 30m right now, make this longer than that */
private static final long MIN_DELAY_FOR_WORSE_STRATUM = 45*60*1000; private static final long MIN_DELAY_FOR_WORSE_STRATUM = 45*60*1000;
@ -44,20 +44,27 @@ public class RouterClock extends Clock {
/** /**
* Specify how far away from the "correct" time the computer is - a positive * Specify how far away from the "correct" time the computer is - a positive
* value means that we are slow, while a negative value means we are fast. * value means that the system time is slow, while a negative value means the system time is fast.
* *
* @param offsetMs the delta from System.currentTimeMillis() (NOT the delta from now())
*/ */
@Override @Override
public void setOffset(long offsetMs, boolean force) { public void setOffset(long offsetMs, boolean force) {
setOffset(offsetMs, force, DEFAULT_STRATUM); setOffset(offsetMs, force, DEFAULT_STRATUM);
} }
/** @since 0.7.12 */ /**
* @since 0.7.12
* @param offsetMs the delta from System.currentTimeMillis() (NOT the delta from now())
*/
private void setOffset(long offsetMs, int stratum) { private void setOffset(long offsetMs, int stratum) {
setOffset(offsetMs, false, stratum); setOffset(offsetMs, false, stratum);
} }
/** @since 0.7.12 */ /**
* @since 0.7.12
* @param offsetMs the delta from System.currentTimeMillis() (NOT the delta from now())
*/
private void setOffset(long offsetMs, boolean force, int stratum) { private void setOffset(long offsetMs, boolean force, int stratum) {
long delta = offsetMs - _offset; long delta = offsetMs - _offset;
if (!force) { if (!force) {
@ -91,7 +98,7 @@ public class RouterClock extends Clock {
} }
// If so configured, check sanity of proposed clock offset // If so configured, check sanity of proposed clock offset
if (Boolean.valueOf(_contextRC.getProperty("router.clockOffsetSanityCheck","true")).booleanValue() && if (_contextRC.getBooleanPropertyDefaultTrue("router.clockOffsetSanityCheck") &&
_alreadyChanged) { _alreadyChanged) {
// Try calculating peer clock skew // Try calculating peer clock skew
@ -192,6 +199,7 @@ public class RouterClock extends Clock {
/* /*
* How far we still have to slew, for diagnostics * How far we still have to slew, for diagnostics
* @since 0.7.12 * @since 0.7.12
* @deprecated for debugging only
*/ */
public long getDeltaOffset() { public long getDeltaOffset() {
return _desiredOffset - _offset; return _desiredOffset - _offset;

View File

@ -14,7 +14,10 @@ import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.router.RouterClock;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.util.RFC822Date;
import net.i2p.util.EepGet; import net.i2p.util.EepGet;
import net.i2p.util.I2PAppThread; import net.i2p.util.I2PAppThread;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -34,6 +37,7 @@ import net.i2p.util.Translate;
* the router log, and the wrapper log. * the router log, and the wrapper log.
*/ */
public class Reseeder { public class Reseeder {
/** FIXME don't keep a static reference, store _isRunning some other way */
private static ReseedRunner _reseedRunner; private static ReseedRunner _reseedRunner;
private final RouterContext _context; private final RouterContext _context;
private final Log _log; private final Log _log;
@ -46,6 +50,10 @@ public class Reseeder {
/** /**
* NOTE - URLs in both the standard and SSL groups should use the same hostname and path, * NOTE - URLs in both the standard and SSL groups should use the same hostname and path,
* so the reseed process will not download from both. * so the reseed process will not download from both.
*
* NOTE - Each seedURL must be a directory, it must end with a '/',
* it can't end with 'index.html', for example. Both because of how individual file
* URLs are constructed, and because SSLEepGet doesn't follow redirects.
*/ */
public static final String DEFAULT_SEED_URL = public static final String DEFAULT_SEED_URL =
"http://a.netdb.i2p2.de/,http://c.netdb.i2p2.de/," + "http://a.netdb.i2p2.de/,http://c.netdb.i2p2.de/," +
@ -98,13 +106,13 @@ public class Reseeder {
private String _proxyHost; private String _proxyHost;
private int _proxyPort; private int _proxyPort;
private SSLEepGet.SSLState _sslState; private SSLEepGet.SSLState _sslState;
private int _gotDate;
private long _attemptStarted;
private static final int MAX_DATE_SETS = 2;
public ReseedRunner() { public ReseedRunner() {
_isRunning = false;
System.clearProperty(PROP_ERROR);
System.setProperty(PROP_STATUS, _("Reseeding"));
System.setProperty(PROP_INPROGRESS, "true");
} }
public boolean isRunning() { return _isRunning; } public boolean isRunning() { return _isRunning; }
/* /*
@ -113,6 +121,11 @@ public class Reseeder {
*/ */
public void run() { public void run() {
_isRunning = true; _isRunning = true;
System.clearProperty(PROP_ERROR);
System.setProperty(PROP_STATUS, _("Reseeding"));
System.setProperty(PROP_INPROGRESS, "true");
_attemptStarted = 0;
_gotDate = 0;
_sslState = null; // start fresh _sslState = null; // start fresh
if (_context.getBooleanProperty(PROP_PROXY_ENABLE)) { if (_context.getBooleanProperty(PROP_PROXY_ENABLE)) {
_proxyHost = _context.getProperty(PROP_PROXY_HOST); _proxyHost = _context.getProperty(PROP_PROXY_HOST);
@ -152,8 +165,48 @@ public class Reseeder {
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {} public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {}
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {} public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {}
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {} public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {}
public void headerReceived(String url, int attemptNum, String key, String val) {}
public void attempting(String url) {} /**
* Use the Date header as a backup time source
*/
public void headerReceived(String url, int attemptNum, String key, String val) {
// We do this more than once, because
// the first SSL handshake may take a while, and it may take the server
// a while to render the index page.
if (_gotDate < MAX_DATE_SETS && "date".equalsIgnoreCase(key) && _attemptStarted > 0) {
long timeRcvd = System.currentTimeMillis();
long serverTime = RFC822Date.parse822Date(val);
if (serverTime > 0) {
// add 500ms since it's 1-sec resolution, and add half the RTT
long now = serverTime + 500 + ((timeRcvd - _attemptStarted) / 2);
long offset = now - _context.clock().now();
if (_context.clock().getUpdatedSuccessfully()) {
// 2nd time better than the first
if (_gotDate > 0)
_context.clock().setNow(now, RouterClock.DEFAULT_STRATUM - 2);
else
_context.clock().setNow(now, RouterClock.DEFAULT_STRATUM - 1);
if (_log.shouldLog(Log.WARN))
_log.warn("Reseed adjusting clock by " +
DataHelper.formatDuration(Math.abs(offset)));
} else {
// No peers or NTP yet, this is probably better than the peer average will be for a while
// default stratum - 1, so the peer average is a worse stratum
_context.clock().setNow(now, RouterClock.DEFAULT_STRATUM - 1);
_log.logAlways(Log.WARN, "NTP failure, Reseed adjusting clock by " +
DataHelper.formatDuration(Math.abs(offset)));
}
_gotDate++;
}
}
}
/** save the start time */
public void attempting(String url) {
if (_gotDate < MAX_DATE_SETS)
_attemptStarted = System.currentTimeMillis();
}
// End of EepGet status listeners // End of EepGet status listeners
/** /**
@ -235,7 +288,8 @@ public class Reseeder {
**/ **/
private int reseedOne(String seedURL, boolean echoStatus) { private int reseedOne(String seedURL, boolean echoStatus) {
try { try {
final long timeLimit = _context.clock().now() + MAX_TIME_PER_HOST; // Don't use context clock as we may be adjusting the time
final long timeLimit = System.currentTimeMillis() + MAX_TIME_PER_HOST;
System.setProperty(PROP_STATUS, _("Reseeding: fetching seed URL.")); System.setProperty(PROP_STATUS, _("Reseeding: fetching seed URL."));
System.err.println("Reseeding from " + seedURL); System.err.println("Reseeding from " + seedURL);
URL dir = new URL(seedURL); URL dir = new URL(seedURL);
@ -275,7 +329,7 @@ public class Reseeder {
int errors = 0; int errors = 0;
// 200 max from one URL // 200 max from one URL
for (Iterator<String> iter = urlList.iterator(); for (Iterator<String> iter = urlList.iterator();
iter.hasNext() && fetched < 200 && _context.clock().now() < timeLimit; ) { iter.hasNext() && fetched < 200 && System.currentTimeMillis() < timeLimit; ) {
try { try {
System.setProperty(PROP_STATUS, System.setProperty(PROP_STATUS,
_("Reseeding: fetching router info from seed URL ({0} successful, {1} errors).", fetched, errors)); _("Reseeding: fetching router info from seed URL ({0} successful, {1} errors).", fetched, errors));

View File

@ -509,7 +509,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
buf.append("<tt>"); buf.append("<tt>");
boolean found = _context.netDb().lookupRouterInfoLocally(peer) != null; boolean found = _context.netDb().lookupRouterInfoLocally(peer) != null;
if (found) if (found)
buf.append("<a title=\"").append(_("NetDb entry")).append("\" href=\"netdb.jsp?r=").append(h).append("\">"); buf.append("<a title=\"").append(_("NetDb entry")).append("\" href=\"netdb?r=").append(h).append("\">");
buf.append(h); buf.append(h);
if (found) if (found)
buf.append("</a>"); buf.append("</a>");

View File

@ -399,7 +399,7 @@ class EstablishState {
_context.clock().setOffset(1000 * (_tsB - _tsA), true); _context.clock().setOffset(1000 * (_tsB - _tsA), true);
_tsA = _tsB; _tsA = _tsB;
if (diff != 0) if (diff != 0)
_log.error("NTP failure, NTCP adjusting clock by " + DataHelper.formatDuration(diff)); _log.logAlways(Log.WARN, "NTP failure, NTCP adjusting clock by " + DataHelper.formatDuration(diff));
} else if (diff >= Router.CLOCK_FUDGE_FACTOR) { } else if (diff >= Router.CLOCK_FUDGE_FACTOR) {
_context.statManager().addRateData("ntcp.invalidOutboundSkew", diff, 0); _context.statManager().addRateData("ntcp.invalidOutboundSkew", diff, 0);
_transport.markReachable(_con.getRemotePeer().calculateHash(), false); _transport.markReachable(_con.getRemotePeer().calculateHash(), false);
@ -617,7 +617,7 @@ class EstablishState {
_context.clock().setOffset(1000 * (_tsB - tsA), true); _context.clock().setOffset(1000 * (_tsB - tsA), true);
tsA = _tsB; tsA = _tsB;
if (diff != 0) if (diff != 0)
_log.error("NTP failure, NTCP adjusting clock by " + DataHelper.formatDuration(diff)); _log.logAlways(Log.WARN, "NTP failure, NTCP adjusting clock by " + DataHelper.formatDuration(diff));
} else if (diff >= Router.CLOCK_FUDGE_FACTOR) { } else if (diff >= Router.CLOCK_FUDGE_FACTOR) {
_context.statManager().addRateData("ntcp.invalidInboundSkew", diff, 0); _context.statManager().addRateData("ntcp.invalidInboundSkew", diff, 0);
_transport.markReachable(alice.calculateHash(), true); _transport.markReachable(alice.calculateHash(), true);

View File

@ -473,7 +473,7 @@ class PacketHandler {
// so we have to wait for NTCP to do it // so we have to wait for NTCP to do it
_context.clock().setOffset(0 - skew, true); _context.clock().setOffset(0 - skew, true);
if (skew != 0) if (skew != 0)
_log.error("NTP failure, UDP adjusting clock by " + DataHelper.formatDuration(Math.abs(skew))); _log.logAlways(Log.WARN, "NTP failure, UDP adjusting clock by " + DataHelper.formatDuration(Math.abs(skew)));
} }
if (skew > GRACE_PERIOD) { if (skew > GRACE_PERIOD) {

View File

@ -0,0 +1,51 @@
package net.i2p.router.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Moved from NewsFetcher
* @since 0.8.5
*/
public abstract class RFC822Date {
/**
* http://jimyjoshi.com/blog/2007/08/rfc822dateparsinginjava.html
* Apparently public domain
* Probably don't need all of these...
*/
private static final SimpleDateFormat rfc822DateFormats[] = new SimpleDateFormat[] {
new SimpleDateFormat("EEE, d MMM yy HH:mm:ss z", Locale.US),
new SimpleDateFormat("EEE, d MMM yy HH:mm z", Locale.US),
new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US),
new SimpleDateFormat("EEE, d MMM yyyy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yy HH:mm:ss z", Locale.US),
new SimpleDateFormat("d MMM yyyy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US)
};
/**
* new Date(String foo) is deprecated, so let's do this the hard way
*
* @param s non-null
* @return -1 on failure
*/
public static long parse822Date(String s) {
for (int i = 0; i < rfc822DateFormats.length; i++) {
try {
Date date = rfc822DateFormats[i].parse(s);
if (date != null)
return date.getTime();
} catch (ParseException pe) {}
}
return -1;
}
/** @since 0.8.2 */
public static String to822Date(long t) {
return (new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US)).format(new Date(t));
}
}