forked from I2P_Developers/i2p.i2p
Compare commits
13 Commits
i2p_0_6_1_
...
i2p_0_6_1_
Author | SHA1 | Date | |
---|---|---|---|
f67f47f0cd | |||
5ad6ee60eb | |||
5accba6cdc | |||
313e1704df | |||
cf4d2b17c9 | |||
9145eedc35 | |||
b772179077 | |||
9054a196ce | |||
d28a96ac7d | |||
9c73f80ac3 | |||
20c46cff04 | |||
f332513755 | |||
cb69a66498 |
@ -92,9 +92,10 @@ public class AddressBook {
|
||||
this.location = subscription.getLocation();
|
||||
EepGet get = new EepGet(I2PAppContext.getGlobalContext(), true,
|
||||
proxyHost, proxyPort, 0, "addressbook.tmp",
|
||||
subscription.getLocation(), true, subscription.getEtag());
|
||||
subscription.getLocation(), true, subscription.getEtag(), subscription.getLastModified());
|
||||
get.fetch();
|
||||
subscription.setEtag(get.getETag());
|
||||
subscription.setLastModified(get.getLastModified());
|
||||
try {
|
||||
this.addresses = ConfigParser.parse(new File("addressbook.tmp"));
|
||||
} catch (IOException exp) {
|
||||
|
@ -95,17 +95,14 @@ class PeerCheckerTask extends TimerTask
|
||||
peer.setRateHistory(upload, download);
|
||||
peer.resetCounters();
|
||||
|
||||
if (Snark.debug >= Snark.DEBUG)
|
||||
{
|
||||
Snark.debug(peer + ":", Snark.DEBUG);
|
||||
Snark.debug(" ul: " + upload/KILOPERSECOND
|
||||
+ " dl: " + download/KILOPERSECOND
|
||||
+ " i: " + peer.isInterested()
|
||||
+ " I: " + peer.isInteresting()
|
||||
+ " c: " + peer.isChoking()
|
||||
+ " C: " + peer.isChoked(),
|
||||
Snark.DEBUG);
|
||||
}
|
||||
Snark.debug(peer + ":", Snark.DEBUG);
|
||||
Snark.debug(" ul: " + upload/KILOPERSECOND
|
||||
+ " dl: " + download/KILOPERSECOND
|
||||
+ " i: " + peer.isInterested()
|
||||
+ " I: " + peer.isInteresting()
|
||||
+ " c: " + peer.isChoking()
|
||||
+ " C: " + peer.isChoked(),
|
||||
Snark.DEBUG);
|
||||
|
||||
// If we are at our max uploaders and we have lots of other
|
||||
// interested peers try to make some room.
|
||||
@ -118,9 +115,8 @@ class PeerCheckerTask extends TimerTask
|
||||
// Check if it still wants pieces from us.
|
||||
if (!peer.isInterested())
|
||||
{
|
||||
if (Snark.debug >= Snark.INFO)
|
||||
Snark.debug("Choke uninterested peer: " + peer,
|
||||
Snark.INFO);
|
||||
Snark.debug("Choke uninterested peer: " + peer,
|
||||
Snark.INFO);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
@ -132,8 +128,7 @@ class PeerCheckerTask extends TimerTask
|
||||
else if (peer.isInteresting() && peer.isChoked())
|
||||
{
|
||||
// If they are choking us make someone else a downloader
|
||||
if (Snark.debug >= Snark.DEBUG)
|
||||
Snark.debug("Choke choking peer: " + peer, Snark.DEBUG);
|
||||
Snark.debug("Choke choking peer: " + peer, Snark.DEBUG);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
@ -146,8 +141,7 @@ class PeerCheckerTask extends TimerTask
|
||||
else if (!peer.isInteresting() && !coordinator.completed())
|
||||
{
|
||||
// If they aren't interesting make someone else a downloader
|
||||
if (Snark.debug >= Snark.DEBUG)
|
||||
Snark.debug("Choke uninteresting peer: " + peer, Snark.DEBUG);
|
||||
Snark.debug("Choke uninteresting peer: " + peer, Snark.DEBUG);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
@ -162,9 +156,8 @@ class PeerCheckerTask extends TimerTask
|
||||
&& download == 0)
|
||||
{
|
||||
// We are downloading but didn't receive anything...
|
||||
if (Snark.debug >= Snark.DEBUG)
|
||||
Snark.debug("Choke downloader that doesn't deliver:"
|
||||
+ peer, Snark.DEBUG);
|
||||
Snark.debug("Choke downloader that doesn't deliver:"
|
||||
+ peer, Snark.DEBUG);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
@ -202,9 +195,8 @@ class PeerCheckerTask extends TimerTask
|
||||
|| uploaders > uploadLimit)
|
||||
&& worstDownloader != null)
|
||||
{
|
||||
if (Snark.debug >= Snark.DEBUG)
|
||||
Snark.debug("Choke worst downloader: " + worstDownloader,
|
||||
Snark.DEBUG);
|
||||
Snark.debug("Choke worst downloader: " + worstDownloader,
|
||||
Snark.DEBUG);
|
||||
|
||||
worstDownloader.setChoking(true);
|
||||
coordinator.uploaders--;
|
||||
|
@ -313,6 +313,9 @@ public class PeerCoordinator implements PeerListener
|
||||
synchronized(peers)
|
||||
{
|
||||
need_more = !peer.isConnected() && peers.size() < MAX_CONNECTIONS;
|
||||
// Check if we already have this peer before we build the connection
|
||||
Peer old = peerIDInList(peer.getPeerID(), peers);
|
||||
need_more = need_more && ((old == null) || (old.getInactiveTime() > 4*60*1000));
|
||||
}
|
||||
|
||||
if (need_more)
|
||||
@ -808,8 +811,8 @@ public class PeerCoordinator implements PeerListener
|
||||
public int allowedUploaders()
|
||||
{
|
||||
if (Snark.overUploadLimit(uploaders)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Over limit, uploaders was: " + uploaders);
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Over limit, uploaders was: " + uploaders);
|
||||
return uploaders - 1;
|
||||
} else if (uploaders < MAX_UPLOADERS)
|
||||
return uploaders + 1;
|
||||
|
@ -63,7 +63,7 @@ public class Snark
|
||||
/**
|
||||
* What level of debug info to show.
|
||||
*/
|
||||
public static int debug = NOTICE;
|
||||
//public static int debug = NOTICE;
|
||||
|
||||
// Whether or not to ask the user for commands while sharing
|
||||
private static boolean command_interpreter = true;
|
||||
@ -505,6 +505,7 @@ public class Snark
|
||||
int i = 0;
|
||||
while (i < args.length)
|
||||
{
|
||||
/*
|
||||
if (args[i].equals("--debug"))
|
||||
{
|
||||
debug = INFO;
|
||||
@ -525,7 +526,7 @@ public class Snark
|
||||
catch (NumberFormatException nfe) { }
|
||||
}
|
||||
}
|
||||
else if (args[i].equals("--port"))
|
||||
else */ if (args[i].equals("--port"))
|
||||
{
|
||||
if (args.length - 1 < i + 1)
|
||||
usage("--port needs port number to listen on");
|
||||
@ -772,7 +773,7 @@ public class Snark
|
||||
totalUploaders += c.uploaders;
|
||||
}
|
||||
int limit = I2PSnarkUtil.instance().getMaxUploaders();
|
||||
Snark.debug("Total uploaders: " + totalUploaders + " Limit: " + limit, Snark.DEBUG);
|
||||
// Snark.debug("Total uploaders: " + totalUploaders + " Limit: " + limit, Snark.DEBUG);
|
||||
return totalUploaders > limit;
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,8 @@ public class Storage
|
||||
}
|
||||
|
||||
String name = baseFile.getName();
|
||||
if (files.size() == 1)
|
||||
if (files.size() == 1) // FIXME: ...and if base file not a directory or should this be the only check?
|
||||
// this makes a bad metainfo if the directory has only one file in it
|
||||
{
|
||||
files = null;
|
||||
lengthsList = null;
|
||||
@ -406,7 +407,7 @@ public class Storage
|
||||
/**
|
||||
* Removes 'suspicious' characters from the give file name.
|
||||
*/
|
||||
private String filterName(String name)
|
||||
private static String filterName(String name)
|
||||
{
|
||||
// XXX - Is this enough?
|
||||
return name.replace(File.separatorChar, '_');
|
||||
@ -438,7 +439,7 @@ public class Storage
|
||||
return f;
|
||||
}
|
||||
|
||||
private File getFileFromNames(File base, List names) throws IOException
|
||||
public static File getFileFromNames(File base, List names)
|
||||
{
|
||||
Iterator it = names.iterator();
|
||||
while (it.hasNext())
|
||||
|
@ -300,8 +300,7 @@ public class TrackerClient extends I2PThread
|
||||
+ "&downloaded=" + downloaded
|
||||
+ "&left=" + left
|
||||
+ ((event != NO_EVENT) ? ("&event=" + event) : "");
|
||||
if (Snark.debug >= Snark.INFO)
|
||||
Snark.debug("Sending TrackerClient request: " + s, Snark.INFO);
|
||||
Snark.debug("Sending TrackerClient request: " + s, Snark.INFO);
|
||||
|
||||
File fetched = I2PSnarkUtil.instance().get(s);
|
||||
if (fetched == null) {
|
||||
@ -315,8 +314,7 @@ public class TrackerClient extends I2PThread
|
||||
|
||||
TrackerInfo info = new TrackerInfo(in, coordinator.getID(),
|
||||
coordinator.getMetaInfo());
|
||||
if (Snark.debug >= Snark.INFO)
|
||||
Snark.debug("TrackerClient response: " + info, Snark.INFO);
|
||||
Snark.debug("TrackerClient response: " + info, Snark.INFO);
|
||||
lastRequestTime = System.currentTimeMillis();
|
||||
|
||||
String failure = info.getFailureReason();
|
||||
|
@ -248,23 +248,31 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
_manager.addMessage("Torrent file deleted: " + f.getAbsolutePath());
|
||||
List files = snark.meta.getFiles();
|
||||
String dataFile = snark.meta.getName();
|
||||
for (int i = 0; files != null && i < files.size(); i++) {
|
||||
// multifile torrents have the getFiles() return lists of lists of filenames, but
|
||||
// each of those lists just contain a single file afaict...
|
||||
File df = new File(_manager.getDataDir(), files.get(i).toString());
|
||||
boolean deleted = FileUtil.rmdir(df, false);
|
||||
if (deleted)
|
||||
_manager.addMessage("Data dir deleted: " + df.getAbsolutePath());
|
||||
else
|
||||
_manager.addMessage("Data dir could not be deleted: " + df.getAbsolutePath());
|
||||
}
|
||||
if (dataFile != null) {
|
||||
f = new File(_manager.getDataDir(), dataFile);
|
||||
boolean deleted = f.delete();
|
||||
if (deleted)
|
||||
f = new File(_manager.getDataDir(), dataFile);
|
||||
if (files == null) { // single file torrent
|
||||
if (f.delete())
|
||||
_manager.addMessage("Data file deleted: " + f.getAbsolutePath());
|
||||
else
|
||||
_manager.addMessage("Data file could not be deleted: " + f.getAbsolutePath());
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < files.size(); i++) { // pass 1 delete files
|
||||
// multifile torrents have the getFiles() return lists of lists of filenames, but
|
||||
// each of those lists just contain a single file afaict...
|
||||
File df = Storage.getFileFromNames(f, (List) files.get(i));
|
||||
if (df.delete())
|
||||
_manager.addMessage("Data file deleted: " + df.getAbsolutePath());
|
||||
else
|
||||
_manager.addMessage("Data file could not be deleted: " + df.getAbsolutePath());
|
||||
}
|
||||
for (int i = files.size() - 1; i >= 0; i--) { // pass 2 delete dirs - not foolproof,
|
||||
// we could sort and do a strict bottom-up
|
||||
File df = Storage.getFileFromNames(f, (List) files.get(i));
|
||||
df = df.getParentFile();
|
||||
if (df == null || !df.exists())
|
||||
continue;
|
||||
if(df.delete())
|
||||
_manager.addMessage("Data dir deleted: " + df.getAbsolutePath());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -297,16 +305,19 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
try {
|
||||
Storage s = new Storage(baseFile, announceURL, null);
|
||||
s.create();
|
||||
s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
|
||||
MetaInfo info = s.getMetaInfo();
|
||||
File torrentFile = new File(baseFile.getParent(), baseFile.getName() + ".torrent");
|
||||
if (torrentFile.exists())
|
||||
throw new IOException("Cannot overwrite an existing .torrent file: " + torrentFile.getPath());
|
||||
_manager.saveTorrentStatus(info, s.getBitField()); // so addTorrent won't recheck
|
||||
// DirMonitor could grab this first, maybe hold _snarks lock?
|
||||
FileOutputStream out = new FileOutputStream(torrentFile);
|
||||
out.write(info.getTorrentData());
|
||||
out.close();
|
||||
_manager.addMessage("Torrent created for " + baseFile.getName() + ": " + torrentFile.getAbsolutePath());
|
||||
// now fire it up, but don't automatically seed it
|
||||
_manager.addTorrent(torrentFile.getCanonicalPath(), false);
|
||||
_manager.addTorrent(torrentFile.getCanonicalPath(), true);
|
||||
_manager.addMessage("Many I2P trackers require you to register new torrents before seeding - please do so before starting " + baseFile.getName());
|
||||
} catch (IOException ioe) {
|
||||
_manager.addMessage("Error creating a torrent for " + baseFile.getAbsolutePath() + ": " + ioe.getMessage());
|
||||
|
@ -122,6 +122,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
"The I2P HTTP Proxy supports http:// requests ONLY. Other protocols such as https:// and ftp:// are not allowed.<BR>")
|
||||
.getBytes();
|
||||
|
||||
private final static byte[] ERR_LOCALHOST =
|
||||
("HTTP/1.1 403 Access Denied\r\n"+
|
||||
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||
"Cache-control: no-cache\r\n"+
|
||||
"\r\n"+
|
||||
"<html><body><H1>I2P ERROR: REQUEST DENIED</H1>"+
|
||||
"Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>")
|
||||
.getBytes();
|
||||
|
||||
/** used to assign unique IDs to the threads / clients. no logic or functionality */
|
||||
private static volatile long __clientId = 0;
|
||||
|
||||
@ -394,6 +403,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
usingWWWProxy = true;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix(requestId) + "Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
|
||||
} else if (host.toLowerCase().startsWith("localhost:")) {
|
||||
if (out != null) {
|
||||
out.write(ERR_LOCALHOST);
|
||||
out.write("<p /><i>Generated on: ".getBytes());
|
||||
out.write(new Date().toString().getBytes());
|
||||
out.write("</i></body></html>\n".getBytes());
|
||||
out.flush();
|
||||
}
|
||||
s.close();
|
||||
return;
|
||||
} else {
|
||||
request = request.substring(pos + 1);
|
||||
pos = request.indexOf("/");
|
||||
|
@ -138,8 +138,6 @@ public class I2PSocketManagerFactory {
|
||||
I2PSession session = client.createSession(myPrivateKeyStream, opts);
|
||||
session.connect();
|
||||
I2PSocketManager sockMgr = createManager(session, opts, "manager");
|
||||
if (sockMgr != null)
|
||||
sockMgr.setDefaultOptions(sockMgr.buildOptions(opts));
|
||||
return sockMgr;
|
||||
} catch (I2PSessionException ise) {
|
||||
_log.error("Error creating session for socket manager", ise);
|
||||
@ -199,4 +197,4 @@ public class I2PSocketManagerFactory {
|
||||
}
|
||||
return i2cpPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,4 +225,5 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
temp.delete();
|
||||
}
|
||||
public void headerReceived(String url, int attemptNum, String key, String val) {}
|
||||
public void attempting(String url) {}
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ public class ReseedHandler {
|
||||
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 headerReceived(String url, int attemptNum, String key, String val) {}
|
||||
public void attempting(String url) {}
|
||||
// End of EepGet status listeners
|
||||
|
||||
/**
|
||||
|
@ -169,6 +169,7 @@ public class UpdateHandler {
|
||||
System.setProperty("net.i2p.router.web.UpdateHandler.updateInProgress", "false");
|
||||
}
|
||||
public void headerReceived(String url, int attemptNum, String key, String val) {}
|
||||
public void attempting(String url) {}
|
||||
}
|
||||
|
||||
private void restart() {
|
||||
|
@ -129,7 +129,7 @@ public class I2PSocketManagerFull implements I2PSocketManager {
|
||||
public long getAcceptTimeout() { return _acceptTimeout; }
|
||||
|
||||
public void setDefaultOptions(I2PSocketOptions options) {
|
||||
_defaultOptions = new ConnectionOptions(options);
|
||||
_defaultOptions = new ConnectionOptions((ConnectionOptions) options);
|
||||
}
|
||||
|
||||
public I2PSocketOptions getDefaultOptions() {
|
||||
|
@ -14,8 +14,8 @@ package net.i2p;
|
||||
*
|
||||
*/
|
||||
public class CoreVersion {
|
||||
public final static String ID = "$Revision: 1.71 $ $Date: 2007-03-17 16:19:10 $";
|
||||
public final static String VERSION = "0.6.1.29";
|
||||
public final static String ID = "$Revision: 1.72 $ $Date: 2007-08-23 19:33:31 $";
|
||||
public final static String VERSION = "0.6.1.30";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Core version: " + VERSION);
|
||||
|
@ -18,6 +18,7 @@ import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.SocketTimeout;
|
||||
|
||||
/**
|
||||
* EepGet [-p localhost:4444]
|
||||
@ -37,7 +38,10 @@ public class EepGet {
|
||||
private long _maxSize; // applied both against whole responses and chunks
|
||||
private String _outputFile;
|
||||
private OutputStream _outputStream;
|
||||
/** url we were asked to fetch */
|
||||
private String _url;
|
||||
/** the URL we actually fetch from (may differ from the _url in case of redirect) */
|
||||
private String _actualURL;
|
||||
private String _postData;
|
||||
private boolean _allowCaching;
|
||||
private List _listeners;
|
||||
@ -52,45 +56,52 @@ public class EepGet {
|
||||
private long _bytesRemaining;
|
||||
private int _currentAttempt;
|
||||
private String _etag;
|
||||
private String _lastModified;
|
||||
private boolean _encodingChunked;
|
||||
private boolean _notModified;
|
||||
private String _contentType;
|
||||
private boolean _transferFailed;
|
||||
private boolean _headersRead;
|
||||
private boolean _aborted;
|
||||
private long _fetchHeaderTimeout;
|
||||
private long _fetchEndTime;
|
||||
private long _fetchInactivityTimeout;
|
||||
private int _redirects;
|
||||
private String _redirectLocation;
|
||||
|
||||
// Constructor 7, calls 3 with: do proxy
|
||||
public EepGet(I2PAppContext ctx, String proxyHost, int proxyPort, int numRetries, String outputFile, String url) {
|
||||
this(ctx, true, proxyHost, proxyPort, numRetries, outputFile, url);
|
||||
}
|
||||
// Constructor 6, calls 1 with: do proxy, no etag
|
||||
public EepGet(I2PAppContext ctx, String proxyHost, int proxyPort, int numRetries, String outputFile, String url, boolean allowCaching) {
|
||||
this(ctx, true, proxyHost, proxyPort, numRetries, outputFile, url, allowCaching, null);
|
||||
}
|
||||
// Constructor 5, calls 3 with: no proxy
|
||||
public EepGet(I2PAppContext ctx, int numRetries, String outputFile, String url) {
|
||||
this(ctx, false, null, -1, numRetries, outputFile, url);
|
||||
}
|
||||
// Constructor 4, calls 1 with: no proxy, no etag
|
||||
public EepGet(I2PAppContext ctx, int numRetries, String outputFile, String url, boolean allowCaching) {
|
||||
this(ctx, false, null, -1, numRetries, outputFile, url, allowCaching, null);
|
||||
}
|
||||
// Constructor 3, calls 1 with: do caching, no etag
|
||||
public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, String outputFile, String url) {
|
||||
this(ctx, shouldProxy, proxyHost, proxyPort, numRetries, outputFile, url, true, null);
|
||||
}
|
||||
// Constructor 2, calls 0 with: no output buffer, do caching, no etag
|
||||
public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, String outputFile, String url, String postData) {
|
||||
this(ctx, shouldProxy, proxyHost, proxyPort, numRetries, -1, -1, outputFile, null, url, true, null, postData);
|
||||
}
|
||||
// Constructor 1, calls 0 with: no output buffer, no postdata
|
||||
public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, String outputFile, String url, boolean allowCaching, String etag) {
|
||||
this(ctx, shouldProxy, proxyHost, proxyPort, numRetries, -1, -1, outputFile, null, url, allowCaching, etag, null);
|
||||
}
|
||||
// Constructor 0, real constructor
|
||||
public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, String outputFile, String url, boolean allowCaching, String etag, String lastModified) {
|
||||
this(ctx, shouldProxy, proxyHost, proxyPort, numRetries, -1, -1, outputFile, null, url, allowCaching, etag, lastModified, null);
|
||||
}
|
||||
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) {
|
||||
this(ctx, shouldProxy, proxyHost, proxyPort, numRetries, minSize, maxSize, outputFile, outputStream, url, allowCaching, etag, null, 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) {
|
||||
String etag, String lastModified, String postData) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(EepGet.class);
|
||||
_shouldProxy = shouldProxy;
|
||||
_shouldProxy = (proxyHost != null) && (proxyHost.length() > 0) && (proxyPort > 0) && shouldProxy;
|
||||
_proxyHost = proxyHost;
|
||||
_proxyPort = proxyPort;
|
||||
_numRetries = numRetries;
|
||||
@ -99,13 +110,19 @@ public class EepGet {
|
||||
_outputFile = outputFile; // if outputFile is set, outputStream must be null
|
||||
_outputStream = outputStream; // if both are set, outputStream overrides outputFile
|
||||
_url = url;
|
||||
_actualURL = url;
|
||||
_postData = postData;
|
||||
_alreadyTransferred = 0;
|
||||
_bytesTransferred = 0;
|
||||
_bytesRemaining = -1;
|
||||
_currentAttempt = 0;
|
||||
_transferFailed = false;
|
||||
_headersRead = false;
|
||||
_aborted = false;
|
||||
_fetchHeaderTimeout = 45*1000;
|
||||
_listeners = new ArrayList(1);
|
||||
_etag = etag;
|
||||
_lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,6 +220,7 @@ public class EepGet {
|
||||
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause);
|
||||
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt);
|
||||
public void headerReceived(String url, int currentAttempt, String key, String val);
|
||||
public void attempting(String url);
|
||||
}
|
||||
private class CLIStatusListener implements StatusListener {
|
||||
private int _markSize;
|
||||
@ -317,6 +335,7 @@ public class EepGet {
|
||||
buf.append("KBps");
|
||||
System.out.println(buf.toString());
|
||||
}
|
||||
public void attempting(String url) {}
|
||||
public void headerReceived(String url, int currentAttempt, String key, String val) {}
|
||||
}
|
||||
|
||||
@ -329,17 +348,48 @@ public class EepGet {
|
||||
* Blocking fetch, returning true if the URL was retrieved, false if all retries failed
|
||||
*
|
||||
*/
|
||||
public boolean fetch() {
|
||||
public boolean fetch() { return fetch(_fetchHeaderTimeout); }
|
||||
/**
|
||||
* Blocking fetch, timing out individual attempts if the HTTP response headers
|
||||
* don't come back in the time given. If the timeout is zero or less, this will
|
||||
* wait indefinitely.
|
||||
*/
|
||||
public boolean fetch(long fetchHeaderTimeout) {
|
||||
return fetch(fetchHeaderTimeout, -1, -1);
|
||||
}
|
||||
public boolean fetch(long fetchHeaderTimeout, long totalTimeout, long inactivityTimeout) {
|
||||
_fetchHeaderTimeout = fetchHeaderTimeout;
|
||||
_fetchEndTime = (totalTimeout > 0 ? System.currentTimeMillis() + totalTimeout : -1);
|
||||
_fetchInactivityTimeout = inactivityTimeout;
|
||||
_keepFetching = true;
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Fetching (proxied? " + _shouldProxy + ") url=" + _url);
|
||||
_log.debug("Fetching (proxied? " + _shouldProxy + ") url=" + _actualURL);
|
||||
while (_keepFetching) {
|
||||
SocketTimeout timeout = null;
|
||||
if (_fetchHeaderTimeout > 0)
|
||||
timeout = new SocketTimeout(_fetchHeaderTimeout);
|
||||
final SocketTimeout stimeout = timeout; // ugly
|
||||
timeout.setTimeoutCommand(new Runnable() {
|
||||
public void run() {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("timeout reached on " + _url + ": " + stimeout);
|
||||
_aborted = true;
|
||||
}
|
||||
});
|
||||
timeout.setTotalTimeoutPeriod(_fetchEndTime);
|
||||
try {
|
||||
sendRequest();
|
||||
doFetch();
|
||||
return true;
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).attempting(_url);
|
||||
sendRequest(timeout);
|
||||
timeout.resetTimer();
|
||||
doFetch(timeout);
|
||||
timeout.cancel();
|
||||
if (!_transferFailed)
|
||||
return true;
|
||||
break;
|
||||
} catch (IOException ioe) {
|
||||
timeout.cancel();
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).attemptFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt, _numRetries, ioe);
|
||||
} finally {
|
||||
@ -360,7 +410,10 @@ public class EepGet {
|
||||
_currentAttempt++;
|
||||
if (_currentAttempt > _numRetries)
|
||||
break;
|
||||
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
||||
try {
|
||||
long delay = _context.random().nextInt(60*1000);
|
||||
Thread.sleep(5*1000+delay);
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
@ -368,9 +421,57 @@ public class EepGet {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** a single fetch attempt */
|
||||
private void doFetch() throws IOException {
|
||||
readHeaders();
|
||||
/** return true if the URL was completely retrieved */
|
||||
private void doFetch(SocketTimeout timeout) throws IOException {
|
||||
_headersRead = false;
|
||||
_aborted = false;
|
||||
try {
|
||||
readHeaders();
|
||||
} finally {
|
||||
_headersRead = true;
|
||||
}
|
||||
if (_aborted)
|
||||
throw new IOException("Timed out reading the HTTP headers");
|
||||
|
||||
timeout.resetTimer();
|
||||
if (_fetchInactivityTimeout > 0)
|
||||
timeout.setInactivityTimeout(_fetchInactivityTimeout);
|
||||
else
|
||||
timeout.setInactivityTimeout(60*1000);
|
||||
|
||||
if (_redirectLocation != null) {
|
||||
try {
|
||||
URL oldURL = new URL(_actualURL);
|
||||
String query = oldURL.getQuery();
|
||||
if (query == null) query = "";
|
||||
if (_redirectLocation.startsWith("http://")) {
|
||||
if ( (_redirectLocation.indexOf('?') < 0) && (query.length() > 0) )
|
||||
_actualURL = _redirectLocation + "?" + query;
|
||||
else
|
||||
_actualURL = _redirectLocation;
|
||||
} else {
|
||||
URL url = new URL(_actualURL);
|
||||
if (_redirectLocation.startsWith("/"))
|
||||
_actualURL = "http://" + url.getHost() + ":" + url.getPort() + _redirectLocation;
|
||||
else
|
||||
_actualURL = "http://" + url.getHost() + ":" + url.getPort() + "/" + _redirectLocation;
|
||||
if ( (_actualURL.indexOf('?') < 0) && (query.length() > 0) )
|
||||
_actualURL = _actualURL + "?" + query;
|
||||
else
|
||||
_actualURL = _actualURL;
|
||||
}
|
||||
} catch (MalformedURLException mue) {
|
||||
throw new IOException("Redirected from an invalid URL");
|
||||
}
|
||||
_redirects++;
|
||||
if (_redirects > 5)
|
||||
throw new IOException("Too many redirects: to " + _redirectLocation);
|
||||
if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
|
||||
sendRequest(timeout);
|
||||
doFetch(timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Headers read completely, reading " + _bytesRemaining);
|
||||
|
||||
@ -384,13 +485,14 @@ public class EepGet {
|
||||
|
||||
int remaining = (int)_bytesRemaining;
|
||||
byte buf[] = new byte[1024];
|
||||
while (_keepFetching && ( (remaining > 0) || !strictSize )) {
|
||||
while (_keepFetching && ( (remaining > 0) || !strictSize ) && !_aborted) {
|
||||
int toRead = buf.length;
|
||||
if (strictSize && toRead > remaining)
|
||||
toRead = remaining;
|
||||
int read = _proxyIn.read(buf, 0, toRead);
|
||||
if (read == -1)
|
||||
break;
|
||||
timeout.resetTimer();
|
||||
_out.write(buf, 0, read);
|
||||
_bytesTransferred += read;
|
||||
// This seems necessary to properly resume a partial download into a stream,
|
||||
@ -400,10 +502,26 @@ public class EepGet {
|
||||
_alreadyTransferred += read;
|
||||
remaining -= read;
|
||||
if (remaining==0 && _encodingChunked) {
|
||||
if(_proxyIn.read()=='\r' && _proxyIn.read()=='\n') {
|
||||
remaining = (int) readChunkLength();
|
||||
int char1 = _proxyIn.read();
|
||||
if (char1 == '\r') {
|
||||
int char2 = _proxyIn.read();
|
||||
if (char2 == '\n') {
|
||||
remaining = (int) readChunkLength();
|
||||
} else {
|
||||
_out.write(char1);
|
||||
_out.write(char2);
|
||||
_bytesTransferred += 2;
|
||||
remaining -= 2;
|
||||
read += 2;
|
||||
}
|
||||
} else {
|
||||
_out.write(char1);
|
||||
_bytesTransferred++;
|
||||
remaining--;
|
||||
read++;
|
||||
}
|
||||
}
|
||||
timeout.resetTimer();
|
||||
if (read > 0)
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).bytesTransferred(
|
||||
@ -413,15 +531,24 @@ public class EepGet {
|
||||
_encodingChunked?-1:_bytesRemaining,
|
||||
_url);
|
||||
}
|
||||
|
||||
|
||||
if (_out != null)
|
||||
_out.close();
|
||||
_out = null;
|
||||
|
||||
if (_aborted)
|
||||
throw new IOException("Timed out reading the HTTP data");
|
||||
|
||||
timeout.cancel();
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Done transferring " + _bytesTransferred);
|
||||
_log.debug("Done transferring " + _bytesTransferred + " (ok? " + !_transferFailed + ")");
|
||||
|
||||
if ( (_bytesRemaining == -1) || (remaining == 0) ){
|
||||
if (_transferFailed) {
|
||||
// 404, etc
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).transferFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt);
|
||||
} else if ( (_bytesRemaining == -1) || (remaining == 0) ) {
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).transferComplete(
|
||||
_alreadyTransferred,
|
||||
@ -442,31 +569,51 @@ public class EepGet {
|
||||
boolean read = DataHelper.readLine(_proxyIn, buf);
|
||||
if (!read) throw new IOException("Unable to read the first line");
|
||||
int responseCode = handleStatus(buf.toString());
|
||||
|
||||
boolean redirect = false;
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("rc: " + responseCode + " for " + _actualURL);
|
||||
boolean rcOk = false;
|
||||
switch (responseCode) {
|
||||
case 200: // full
|
||||
if (_outputStream != null) _out = _outputStream;
|
||||
else _out = new FileOutputStream(_outputFile, false);
|
||||
if (_outputStream != null)
|
||||
_out = _outputStream;
|
||||
else
|
||||
_out = new FileOutputStream(_outputFile, false);
|
||||
_alreadyTransferred = 0;
|
||||
rcOk = true;
|
||||
break;
|
||||
case 206: // partial
|
||||
if (_outputStream != null) _out = _outputStream;
|
||||
else _out = new FileOutputStream(_outputFile, true);
|
||||
if (_outputStream != null)
|
||||
_out = _outputStream;
|
||||
else
|
||||
_out = new FileOutputStream(_outputFile, true);
|
||||
rcOk = true;
|
||||
break;
|
||||
case 301: // various redirections
|
||||
case 302:
|
||||
case 303:
|
||||
case 307:
|
||||
_alreadyTransferred = 0;
|
||||
rcOk = true;
|
||||
redirect = true;
|
||||
break;
|
||||
case 304: // not modified
|
||||
_bytesRemaining = 0;
|
||||
_keepFetching = false;
|
||||
_notModified = true;
|
||||
return;
|
||||
return;
|
||||
case 404: // not found
|
||||
_keepFetching = false;
|
||||
_transferFailed = true;
|
||||
return;
|
||||
case 416: // completed (or range out of reach)
|
||||
_bytesRemaining = 0;
|
||||
_keepFetching = false;
|
||||
return;
|
||||
default:
|
||||
rcOk = false;
|
||||
_transferFailed = true;
|
||||
}
|
||||
buf.setLength(0);
|
||||
byte lookahead[] = new byte[3];
|
||||
@ -500,6 +647,7 @@ public class EepGet {
|
||||
if (_encodingChunked) {
|
||||
_bytesRemaining = readChunkLength();
|
||||
}
|
||||
if (!redirect) _redirectLocation = null;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -589,11 +737,15 @@ public class EepGet {
|
||||
}
|
||||
} else if (key.equalsIgnoreCase("ETag")) {
|
||||
_etag = val.trim();
|
||||
} else if (key.equalsIgnoreCase("Last-Modified")) {
|
||||
_lastModified = val.trim();
|
||||
} else if (key.equalsIgnoreCase("Transfer-encoding")) {
|
||||
if (val.indexOf("chunked") != -1)
|
||||
_encodingChunked = true;
|
||||
} else if (key.equalsIgnoreCase("Content-Type")) {
|
||||
_contentType=val;
|
||||
} else if (key.equalsIgnoreCase("Location")) {
|
||||
_redirectLocation=val.trim();
|
||||
} else {
|
||||
// ignore the rest
|
||||
}
|
||||
@ -616,13 +768,13 @@ public class EepGet {
|
||||
private static final byte NL = '\n';
|
||||
private boolean isNL(byte b) { return (b == NL); }
|
||||
|
||||
private void sendRequest() throws IOException {
|
||||
private void sendRequest(SocketTimeout timeout) throws IOException {
|
||||
if (_outputStream != null) {
|
||||
// We are reading into a stream supplied by a caller,
|
||||
// for which we cannot easily determine how much we've written.
|
||||
// Assume that _alreadyTransferred holds the right value
|
||||
// (we should never be restarted to work on an old stream).
|
||||
} else {
|
||||
} else {
|
||||
File outFile = new File(_outputFile);
|
||||
if (outFile.exists())
|
||||
_alreadyTransferred = outFile.length();
|
||||
@ -630,24 +782,34 @@ public class EepGet {
|
||||
|
||||
String req = getRequest();
|
||||
|
||||
if (_proxyIn != null) try { _proxyIn.close(); } catch (IOException ioe) {}
|
||||
if (_proxyOut != null) try { _proxyOut.close(); } catch (IOException ioe) {}
|
||||
if (_proxy != null) try { _proxy.close(); } catch (IOException ioe) {}
|
||||
|
||||
if (_shouldProxy) {
|
||||
_proxy = new Socket(_proxyHost, _proxyPort);
|
||||
} else {
|
||||
try {
|
||||
URL url = new URL(_url);
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
if (port == -1)
|
||||
port = 80;
|
||||
_proxy = new Socket(host, port);
|
||||
URL url = new URL(_actualURL);
|
||||
if ("http".equals(url.getProtocol())) {
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
if (port == -1)
|
||||
port = 80;
|
||||
_proxy = new Socket(host, port);
|
||||
} else {
|
||||
throw new IOException("URL is not supported:" + _actualURL);
|
||||
}
|
||||
} catch (MalformedURLException mue) {
|
||||
throw new IOException("Request URL is invalid");
|
||||
}
|
||||
}
|
||||
_proxyIn = _proxy.getInputStream();
|
||||
_proxyOut = _proxy.getOutputStream();
|
||||
|
||||
_proxyOut.write(req.toString().getBytes());
|
||||
|
||||
timeout.setSocket(_proxy);
|
||||
|
||||
_proxyOut.write(DataHelper.getUTF8(req.toString()));
|
||||
_proxyOut.flush();
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -659,12 +821,24 @@ public class EepGet {
|
||||
boolean post = false;
|
||||
if ( (_postData != null) && (_postData.length() > 0) )
|
||||
post = true;
|
||||
URL url = new URL(_actualURL);
|
||||
String proto = url.getProtocol();
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
String path = url.getPath();
|
||||
String query = url.getQuery();
|
||||
if (query != null)
|
||||
path = path + "?" + query;
|
||||
if (!path.startsWith("/"))
|
||||
path = "/" + path;
|
||||
if ( (port == 80) || (port == 443) || (port <= 0) ) path = proto + "://" + host + path;
|
||||
else path = proto + "://" + host + ":" + port + path;
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug("Requesting " + path);
|
||||
if (post) {
|
||||
buf.append("POST ").append(_url).append(" HTTP/1.1\r\n");
|
||||
buf.append("POST ").append(_actualURL).append(" HTTP/1.1\r\n");
|
||||
} else {
|
||||
buf.append("GET ").append(_url).append(" HTTP/1.1\r\n");
|
||||
buf.append("GET ").append(_actualURL).append(" HTTP/1.1\r\n");
|
||||
}
|
||||
URL url = new URL(_url);
|
||||
buf.append("Host: ").append(url.getHost()).append("\r\n");
|
||||
if (_alreadyTransferred > 0) {
|
||||
buf.append("Range: bytes=");
|
||||
@ -677,11 +851,16 @@ public class EepGet {
|
||||
buf.append("Cache-control: no-cache\r\n");
|
||||
buf.append("Pragma: no-cache\r\n");
|
||||
}
|
||||
if (_etag != null) {
|
||||
if ((_etag != null) && (_alreadyTransferred <= 0)) {
|
||||
buf.append("If-None-Match: ");
|
||||
buf.append(_etag);
|
||||
buf.append("\r\n");
|
||||
}
|
||||
if ((_lastModified != null) && (_alreadyTransferred <= 0)) {
|
||||
buf.append("If-Modified-Since: ");
|
||||
buf.append(_lastModified);
|
||||
buf.append("\r\n");
|
||||
}
|
||||
if (post)
|
||||
buf.append("Content-length: ").append(_postData.length()).append("\r\n");
|
||||
buf.append("Connection: close\r\n\r\n");
|
||||
@ -696,6 +875,10 @@ public class EepGet {
|
||||
return _etag;
|
||||
}
|
||||
|
||||
public String getLastModified() {
|
||||
return _lastModified;
|
||||
}
|
||||
|
||||
public boolean getNotModified() {
|
||||
return _notModified;
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ public class EepGetScheduler implements EepGet.StatusListener {
|
||||
public void fetch(boolean shouldBlock) {
|
||||
//Checking for a valid index is done in fetchNext, so we don't have to worry about it.
|
||||
if (shouldBlock) {
|
||||
fetchNext();
|
||||
while (_curURL < _urls.size())
|
||||
fetchNext();
|
||||
} else {
|
||||
fetch();
|
||||
}
|
||||
@ -77,6 +78,7 @@ public class EepGetScheduler implements EepGet.StatusListener {
|
||||
_listener.transferFailed(url, bytesTransferred, bytesRemaining, currentAttempt);
|
||||
fetchNext();
|
||||
}
|
||||
public void attempting(String url) { _listener.attempting(url); }
|
||||
|
||||
public void headerReceived(String url, int attemptNum, String key, String val) {}
|
||||
}
|
||||
|
71
core/java/src/net/i2p/util/SocketTimeout.java
Normal file
71
core/java/src/net/i2p/util/SocketTimeout.java
Normal file
@ -0,0 +1,71 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class SocketTimeout implements SimpleTimer.TimedEvent {
|
||||
private Socket _targetSocket;
|
||||
private long _startTime;
|
||||
private long _inactivityDelay;
|
||||
private long _lastActivity;
|
||||
private long _totalTimeoutTime;
|
||||
private boolean _cancelled;
|
||||
private Runnable _command;
|
||||
public SocketTimeout(long delay) { this(null, delay); }
|
||||
public SocketTimeout(Socket socket, long delay) {
|
||||
_inactivityDelay = delay;
|
||||
_targetSocket = socket;
|
||||
_cancelled = false;
|
||||
_lastActivity = _startTime = System.currentTimeMillis();
|
||||
_totalTimeoutTime = -1;
|
||||
SimpleTimer.getInstance().addEvent(SocketTimeout.this, delay);
|
||||
}
|
||||
public void timeReached() {
|
||||
if (_cancelled) return;
|
||||
|
||||
if ( ( (_totalTimeoutTime > 0) && (_totalTimeoutTime <= System.currentTimeMillis()) ) ||
|
||||
(_inactivityDelay + _lastActivity <= System.currentTimeMillis()) ) {
|
||||
if (_targetSocket != null) {
|
||||
try {
|
||||
if (!_targetSocket.isClosed())
|
||||
_targetSocket.close();
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
if (_command != null) _command.run();
|
||||
} else {
|
||||
SimpleTimer.getInstance().addEvent(SocketTimeout.this, _inactivityDelay);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
_cancelled = true;
|
||||
SimpleTimer.getInstance().removeEvent(SocketTimeout.this);
|
||||
}
|
||||
public void setSocket(Socket s) { _targetSocket = s; }
|
||||
public void resetTimer() { _lastActivity = System.currentTimeMillis(); }
|
||||
public void setInactivityTimeout(long timeout) { _inactivityDelay = timeout; }
|
||||
public void setTotalTimeoutPeriod(long timeoutPeriod) {
|
||||
if (timeoutPeriod > 0)
|
||||
_totalTimeoutTime = _startTime + timeoutPeriod;
|
||||
else
|
||||
_totalTimeoutTime = -1;
|
||||
}
|
||||
public void setTimeoutCommand(Runnable job) { _command = job; }
|
||||
|
||||
private static final SimpleDateFormat _fmt = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
|
||||
private static String ts(long when) { synchronized (_fmt) { return _fmt.format(new Date(when)); } }
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("started on ");
|
||||
buf.append(ts(_startTime));
|
||||
buf.append("idle for ");
|
||||
buf.append(System.currentTimeMillis() - _lastActivity);
|
||||
buf.append("ms ");
|
||||
if (_totalTimeoutTime > 0)
|
||||
buf.append("total timeout at ").append(ts(_totalTimeoutTime));
|
||||
buf.append("cancelled? ").append(_cancelled);
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
44
history.txt
44
history.txt
@ -1,4 +1,46 @@
|
||||
$Id: history.txt,v 1.583 2007-08-13 14:42:59 zzz Exp $
|
||||
$Id: history.txt,v 1.592 2007-10-07 21:36:17 complication Exp $
|
||||
|
||||
* 2007-10-07 0.6.1.30 released
|
||||
|
||||
2007-10-07 Complication
|
||||
* Fix an issue in EepGet whereby sending of "etag" and "lastModified" headers
|
||||
broke retrying.
|
||||
|
||||
2007-09-27 zzz
|
||||
* Implement pushback of NTCP transport backlog to the outbound tunnel selection code
|
||||
* Clean up the NTCP and UDP tables on peers.jsp to be consistent,
|
||||
fix some of the sorting
|
||||
|
||||
2007-09-22 zzz
|
||||
* Send messages for the same destination out the same outbound
|
||||
tunnel to reduce out-of-order delivery.
|
||||
|
||||
2007-09-19 zzz
|
||||
* i2psnark: Fix broken multifile torrent Delete;
|
||||
cleanup Storage resources in AddTorrent;
|
||||
don't autostart torrent after Create
|
||||
|
||||
2007-09-18 zzz
|
||||
* eepsite_index.html: Add links to trevorreznik address book
|
||||
* streaming lib: Fix SocketManagerFactory to honor options on outbound connections
|
||||
* streaming lib: Fix setDefaultOptions() when called with a ConnectionOptions parameter
|
||||
* i2psnark: Don't make outbound connections to already-connected peers
|
||||
* i2psnark: Debug logging cleanup
|
||||
|
||||
2007-09-14 zzz
|
||||
* eepget: Increase header timeout to 45s
|
||||
* HTTP proxy: Return a better error message for localhost requests
|
||||
* tunnels: Fix PooledTunnelCreatorConfig memory leak
|
||||
|
||||
2007-09-09 zzz
|
||||
* eepget: Add support for Last-Modified and If-Modified-Since
|
||||
* addressbook: Finish incomplete support for Last-Modified
|
||||
|
||||
2007-09-08 zzz
|
||||
* eepget: Copy over SocketTimeout.java file from syndie
|
||||
|
||||
2007-09-07 jrandom
|
||||
* eepget: Merge timeout support from syndie
|
||||
|
||||
* 2007-08-23 0.6.1.29 released
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
; TC's hosts.txt guaranteed freshness
|
||||
; $Id: hosts.txt,v 1.169 2006-12-16 17:31:07 jrandom Exp $
|
||||
; $Id: hosts.txt,v 1.170 2007-02-12 05:26:21 jrandom Exp $
|
||||
; changelog:
|
||||
; (1.192) added trevorreznik.i2p
|
||||
; (1.191) added trac.i2p
|
||||
; (1.190) added archive.syndie.i2p
|
||||
; (1.189) added mtn.i2p
|
||||
@ -504,4 +505,5 @@ ninja.i2p=XhyN8MgL6DwWE98g2DJlDLHy~02g58IF14LTb472cmSLRj~cHv7wyi1mxy21vtf12oPWRq
|
||||
mtn.i2p=RqXC4xbFK6t3g2wk9SO4RjY7mj1c0DmtMra5c1Md8t-DcNPSjQFmqT97pcZ5IR1JDKqyCO7RI~aATTTMPQexoEeqK9-6Poeh2RA1C81FzcA9sHvjLeg3eB1Cju-sE-IDeFntEvCC4w7wWnpmLzCfdXK7OjSK1wYc6OkqPOLVDEy-N-4UUPlZFWWUghpjBGXGayXz6JRKtoMIwhFQaiKdRvAs32ozM9RM0NWzrCaRLZBIQ6Gg1Ys1wF0-oBJgC4T4CN6SxJNaz9Dfw4GNtPyD6lq3S1osY1ccflm3itvUt3JC1J9ypoXzylBE5MuS-LTgbgbMdMFty07AoWB~EY8TwW8EQQO07GSzB7hm53u0iCEH44GexhKHtQP-hYbIr3mklo89BvfWIRGMTwUkAzYojzC-vOyIh16LWrQQhGbLvByKQSdWk9nInm3GEfqRVtSpuqd4m6iHzrBDZ3fvKjbuywot3hDNHitOHOedmBNA8neCzLkod8b0Z4xx~qRIEObxAAAA
|
||||
archive.syndie.i2p=iXX0DadZTJQpPr1to0OmQ4xokHgx1HYd5ec7~zIjQ80W~p4kRCYJmEzibH2Kn59Gi04SAXeA2O9i3bNqfGCQjsbz7UcjPGrW6-UrckXVXW67Moxp7QWY6i-aKuVYM3bqYxUL2mWvcDzJ8D0ecMpvasxhxwXpdFn2J6CGboMxeGV8R3hwwlNYbYoKgHr74qEJaIZpm1FrRWvNHV5cMv363iWnPy72XspQefk79-VOjPsxfummosU7gqlxl5teyiGKNzMs3G6iJyfVHO8IlKtdn~P~ET9p7zWlTPgV8NTyCVB-Wn5S3JMkMGOFZR7wSlxSwGFpTFQKc7mxVTtLZ5nWcV2OhvOIxRZ31RvGJZyVs562RC5aMfyqcM5IHQiZVlmkhzJKIy9VDw8tKayQtRM-xeN5k6Qr7iMmYIRORwuAODkYApoMD9a0eJ6ZYOSgBMOCSvYcwfT8axRY~GabiHm0QC82mo-nDgrUypGKtOPMI9MIqMTsb8Yl-UGWn6twBAIzAAAA
|
||||
trac.i2p=OBnF9NtkEsPij2F-lp3bWDVrJsPQQPdq6adlpq0N4BY1XRjtDBZl~EpDdk7roq49~ptKAQG2cNUeBEKIIrdlZhJio5pMwUl6YinizzkNTFfZipB5OKoB7PBulxkw-N9mKMhS1btd9ajcV8tiP3xiv7VSlgiDwbdKg1fmkvNrVrJnzkN3-ey2kebYnbh7jjU2gPFUl~CwSEkIi6AK9EfqmFR-DUVohyygqAY~fi4EMeTVXGUqftXSNFYUwpRJgFrWRPTurtZnJK5403q67oEk0eWrPIZ8ytJWSBfffAXL3ts~0O1FZeKXUccsAl33j70~lklSolNVLJ40y-6X5ZLWajmX0ONU3j0qI5A~7fgNgsg-vKypPDuzl8ug-D~BmhqdAf0sRYmziDVwTgU~WRB6IzhhXFR6CbwrGXdgOGg2qNT1eOnMwGo3SMMJ7kK88VC5LdYg2dyiyjZATuvT92QdZglrVQIeBqAehcFjOBuycC1ED3AOak8D9Xplj7V6hN-HAAAA
|
||||
trevorreznik.i2p=FxoG5dx6WuF8gu0Fc4ItB61hd8dBZ0L6FjkvoA-kQrC0DcY5YUqKBUmrcxzKhKo4nLyg0jRV-RSNUuWsali44dmpHQ6wuFjCGTr5zMk0NoVUpBsBNtHLEQWxROnuQFlQAq6x~eVdU5bAvnNFd-6RXDJ86Br9bf5YG4PHmZPon7ld3t1kAvPaZepITKlIq5iXy3va-pzAMFEIhDtLMzFjGhLWMg9m-8tkx4577WvzUWbSAUdxKkxwjecIzbTDTQsZld~t5MkaMmn5UpNX6Gh3iDUPWHXOjn4I8MIELiSaeRdpHDgua3mo~p8oO0QvWBgn~jQ8yr6nz7vMAdoRtOwPlUqHCCM1BsPVcN9a92rPpTFBk0BXikjJJrkDDIaFjJnKmRAsEUoa-eHaPV~RS0QPrfuzlp0XjBzQcAQjNIw6hO4xqJujSs8SdObMpQAqCR5Sc5NzOvTr5eAzCIz0gmQnKrA1RJVOebKDERM~qQ6rFrdVDkjLEJd6SyjUr-TdIrayAAAA
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<i2p.news date="$Date: 2007-03-17 20:47:59 $">
|
||||
<i2p.release version="0.6.1.29" date="2007/02/15" minVersion="0.6"
|
||||
<i2p.news date="$Date: 2007-08-23 19:33:29 $">
|
||||
<i2p.release version="0.6.1.30" date="2007/02/15" minVersion="0.6"
|
||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
|
||||
publicurl="http://dev.i2p.net/i2p/i2pupdate.sud"
|
||||
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-September/000878.html"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<info>
|
||||
<appname>i2p</appname>
|
||||
<appversion>0.6.1.29</appversion>
|
||||
<appversion>0.6.1.30</appversion>
|
||||
<authors>
|
||||
<author name="I2P" email="support@i2p.net"/>
|
||||
</authors>
|
||||
|
@ -52,22 +52,32 @@
|
||||
<li>Before you tell the world about your new eepsite, you should add some content.
|
||||
Go to i2p/eepsite/docroot and copy this document (index.html) to help.html so you can refer to it later.
|
||||
Now edit index.html and add content, pictures, and whatever you would like to share.
|
||||
<li>Now it's time to add your eepsite to I2P's most popular address book.
|
||||
To do that, you must to tell <a href="http://orion.i2p/">orion.i2p</a>
|
||||
what your eepsite name and key are. Orion has a web interface where you can add a key to the address book.
|
||||
The key entry form is <a href="http://orion.i2p/list/">here</a>.
|
||||
<li>Now it's time to add your eepsite to an I2P address book
|
||||
such as <a href="http://orion.i2p/">orion.i2p</a> or
|
||||
<a href="http://trevorreznik.i2p/">trevorreznik.i2p</a>.
|
||||
That is, you must enter
|
||||
your eepsite name and key into a web interface on one or more of these sites.
|
||||
Here is <a href="http://orion.i2p/list/">the key entry form at orion.i2p</a> and
|
||||
here is <a href="http://trevorreznik.i2p/host-database/">the key entry form at trevorreznik.i2p</a>.
|
||||
Again, your key is the entire "Local destination" key on the
|
||||
<a href="http://localhost:7657/i2ptunnel/edit.jsp?tunnel=3">eepsite i2ptunnel configuration page</a>.
|
||||
Be sure you get the whole thing, ending with "AAAA".
|
||||
Don't forget to click "add a key".
|
||||
Check to see if it reports the key was added.
|
||||
Since most routers periodically get address book updates from orion, within several hours others will be able to find your
|
||||
Since many routers periodically get address book updates from orion or trevorreznik, within several hours others will be able to find your
|
||||
website by simply typing <i>something</i>.i2p into their browser.
|
||||
<li>If you are in a hurry and can't wait a few hours, you can tell people to use orion's "jump" address helper redirection service.
|
||||
This will work within a few minutes of your entering the key to orion.i2p.
|
||||
Test it yourself first by entering http://orion.i2p/jump/<i>something</i>.i2p into your browser.
|
||||
<li>Speaking of address book updates, this would be a good time to add orion, trevorreznik, or both
|
||||
to your own subscription list. Go to your <a href="http://localhost:7657/susidns/subscriptions.jsp">subscriptions configuration page</a>
|
||||
and add <a href="http://orion.i2p/hosts.txt">http://orion.i2p/hosts.txt</a> and/or
|
||||
<a href="http://trevorreznik.i2p/hosts.txt">http://trevorreznik.i2p/hosts.txt</a> to the list and hit "Save".
|
||||
Now you will get updates too!
|
||||
<li>If you are in a hurry and can't wait a few hours, you can tell people to use a "jump" address helper redirection service.
|
||||
This will work within a few minutes of your entering the key to an address book.
|
||||
Test it yourself first by entering http://orion.i2p/jump/<i>something</i>.i2p
|
||||
or http://trevorreznik.i2p/cgi-bin/jump.php?hostname=<i>something</i>.i2p/ into your browser.
|
||||
Once it's working, then you can tell others to use it.
|
||||
<li>Some people check <a href="http://orion.i2p/list/">orion.i2p/list/</a> for new eepsites, so you may start getting
|
||||
<li>Some people check <a href="http://orion.i2p/list/">orion.i2p/list/</a> and
|
||||
<a href="http://inproxy.tino.i2p/status.php">inproxy.tino.i2p/status.php</a> for new eepsites, so you may start getting
|
||||
a few visitors. But there are plenty of other ways to tell people. Here are a few ideas:
|
||||
<ul>
|
||||
<li>Post a message on the <a href="http://forum.i2p/viewforum.php?f=16">Eepsite announce forum</a>
|
||||
@ -78,9 +88,10 @@
|
||||
</ul>
|
||||
Note that some sites recommend pasting in that really long destination key.
|
||||
You can if you want - but
|
||||
if you have successfully posted your key on the <a href="http://orion.i2p/list/">orion page here</a>,
|
||||
tested it using http://orion.i2p/jump/<i>something</i>.i2p, and waited 24 hours for orion's
|
||||
address book to propagate to others, that shouldn't be necessary.
|
||||
if you have successfully posted your key at <a href="http://orion.i2p/list/">orion</a> or
|
||||
<a href="http://trevorreznik.i2p/host-database/">trevorreznik</a>,
|
||||
tested it using a jump service, and waited 24 hours for the
|
||||
address book update to propagate to others, that shouldn't be necessary.
|
||||
<li>If you have any questions try IRC #i2p or the
|
||||
<a href="http://forum.i2p/viewforum.php?f=10">technical problems section</a> on
|
||||
<a href="http://forum.i2p/">forum.i2p</a>.
|
||||
|
23
news.xml
23
news.xml
@ -1,5 +1,5 @@
|
||||
<i2p.news date="$Date: 2007-07-19 13:05:44 $">
|
||||
<i2p.release version="0.6.1.29" date="2007/02/15" minVersion="0.6"
|
||||
<i2p.news date="$Date: 2007-08-23 21:34:40 $">
|
||||
<i2p.release version="0.6.1.30" date="2007/02/15" minVersion="0.6"
|
||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
|
||||
publicurl="http://dev.i2p.net/i2p/i2pupdate.sud"
|
||||
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-September/000878.html"
|
||||
@ -10,21 +10,12 @@
|
||||
anonlogs="http://i2p/Nf3ab-ZFkmI-LyMt7GjgT-jfvZ3zKDl0L96pmGQXF1B82W2Bfjf0n7~288vafocjFLnQnVcmZd~-p0-Oolfo9aW2Rm-AhyqxnxyLlPBqGxsJBXjPhm1JBT4Ia8FB-VXt0BuY0fMKdAfWwN61-tj4zIcQWRxv3DFquwEf035K~Ra4SWOqiuJgTRJu7~o~DzHVljVgWIzwf8Z84cz0X33pv-mdG~~y0Bsc2qJVnYwjjR178YMcRSmNE0FVMcs6f17c6zqhMw-11qjKpY~EJfHYCx4lBWF37CD0obbWqTNUIbL~78vxqZRT3dgAgnLixog9nqTO-0Rh~NpVUZnoUi7fNR~awW5U3Cf7rU7nNEKKobLue78hjvRcWn7upHUF45QqTDuaM3yZa7OsjbcH-I909DOub2Q0Dno6vIwuA7yrysccN1sbnkwZbKlf4T6~iDdhaSLJd97QCyPOlbyUfYy9QLNExlRqKgNVJcMJRrIual~Lb1CLbnzt0uvobM57UpqSAAAA/meeting141"
|
||||
publiclogs="http://www.i2p.net/meeting141" />
|
||||
•
|
||||
2007-07-19:
|
||||
We need bandwidth!
|
||||
Please help the network by
|
||||
<a href="/config.jsp">increasing your bandwidth limits and share percentage</a>.
|
||||
Unless the share percentage times the minimum rate is more than 16KBps,
|
||||
you are not sharing at all!
|
||||
Increasing your rate limits will also help your own transfer rates.
|
||||
Thanks!
|
||||
<br />
|
||||
•
|
||||
2007-03-17: 0.6.1.28
|
||||
<a href="http://dev.i2p/pipermail/i2p/2007-March/001340.html">released</a>
|
||||
2007-10-07: 0.6.1.30
|
||||
<a href="http://dev.i2p/pipermail/i2p/2007-October/001356.html">released</a>
|
||||
with
|
||||
streaming lib optimizations, i2psnark
|
||||
improvements, and priority operation within the router.
|
||||
sharing by low-bandwidth routers, automatic inbound NTCP addressing,
|
||||
a new reseed handler, and some i2psnark improvements.
|
||||
Delete the old webapps/syndie.war before restarting to save some memory.
|
||||
<br />
|
||||
•
|
||||
2007-04-10:
|
||||
|
@ -14,6 +14,7 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterAddress;
|
||||
|
||||
/**
|
||||
@ -52,6 +53,7 @@ public abstract class CommSystemFacade implements Service {
|
||||
*/
|
||||
public short getReachabilityStatus() { return STATUS_OK; }
|
||||
public void recheckReachability() {}
|
||||
public boolean isBacklogged(Hash dest) { return false; }
|
||||
|
||||
/**
|
||||
* Tell other transports our address changed
|
||||
|
@ -15,8 +15,8 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.518 $ $Date: 2007-08-13 14:43:01 $";
|
||||
public final static String VERSION = "0.6.1.29";
|
||||
public final static String ID = "$Revision: 1.528 $ $Date: 2007-10-07 21:36:20 $";
|
||||
public final static String VERSION = "0.6.1.30";
|
||||
public final static long BUILD = 0;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||
|
@ -41,6 +41,9 @@ public interface TunnelManagerFacade extends Service {
|
||||
*
|
||||
*/
|
||||
boolean isInUse(Hash peer);
|
||||
|
||||
/** Is a tunnel a valid member of the pool? */
|
||||
public boolean isValidTunnel(Hash client, TunnelInfo tunnel);
|
||||
|
||||
/** how many tunnels are we participating in? */
|
||||
public int getParticipatingCount();
|
||||
@ -85,6 +88,7 @@ class DummyTunnelManagerFacade implements TunnelManagerFacade {
|
||||
public TunnelInfo selectOutboundTunnel() { return null; }
|
||||
public TunnelInfo selectOutboundTunnel(Hash destination) { return null; }
|
||||
public boolean isInUse(Hash peer) { return false; }
|
||||
public boolean isValidTunnel(Hash client, TunnelInfo tunnel) { return false; }
|
||||
public int getParticipatingCount() { return 0; }
|
||||
public int getFreeTunnelCount() { return 0; }
|
||||
public int getOutboundTunnelCount() { return 0; }
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -378,7 +379,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
+ _lease.getTunnelId() + " on "
|
||||
+ _lease.getGateway().toBase64());
|
||||
|
||||
_outTunnel = selectOutboundTunnel();
|
||||
_outTunnel = selectOutboundTunnel(_to);
|
||||
if (_outTunnel != null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getJobId() + ": Sending tunnel message out " + _outTunnel.getSendTunnelId(0) + " to "
|
||||
@ -434,6 +435,46 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use the same outbound tunnel as we did for the same destination previously,
|
||||
* if possible, to keep the streaming lib happy
|
||||
*
|
||||
*/
|
||||
private static HashMap _tunnelCache = new HashMap();
|
||||
private static long _cleanTime = 0;
|
||||
private TunnelInfo selectOutboundTunnel(Destination to) {
|
||||
TunnelInfo tunnel;
|
||||
long now = getContext().clock().now();
|
||||
synchronized (_tunnelCache) {
|
||||
if (now - _cleanTime > 5*60*1000) { // clean out periodically
|
||||
List deleteList = new ArrayList();
|
||||
for (Iterator iter = _tunnelCache.keySet().iterator(); iter.hasNext(); ) {
|
||||
Destination dest = (Destination) iter.next();
|
||||
tunnel = (TunnelInfo) _tunnelCache.get(dest);
|
||||
if (!getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel))
|
||||
deleteList.add(dest);
|
||||
}
|
||||
for (Iterator iter = deleteList.iterator(); iter.hasNext(); ) {
|
||||
Destination dest = (Destination) iter.next();
|
||||
_tunnelCache.remove(dest);
|
||||
}
|
||||
_cleanTime = now;
|
||||
}
|
||||
tunnel = (TunnelInfo) _tunnelCache.get(to);
|
||||
if (tunnel != null) {
|
||||
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel) &&
|
||||
(tunnel.getLength() <= 1 || !getContext().commSystem().isBacklogged(tunnel.getPeer(1))))
|
||||
return(tunnel);
|
||||
else
|
||||
_tunnelCache.remove(to);
|
||||
}
|
||||
tunnel = selectOutboundTunnel();
|
||||
if (tunnel != null)
|
||||
_tunnelCache.put(to, tunnel);
|
||||
}
|
||||
return tunnel;
|
||||
}
|
||||
/**
|
||||
* Pick an arbitrary outbound tunnel to send the message through, or null if
|
||||
* there aren't any around
|
||||
|
@ -19,6 +19,7 @@ import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.Collections;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.OutNetMessage;
|
||||
@ -120,6 +121,10 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
GetBidsJob.getBids(_context, this, msg);
|
||||
}
|
||||
|
||||
public boolean isBacklogged(Hash dest) {
|
||||
return _manager.isBacklogged(dest);
|
||||
}
|
||||
|
||||
public List getMostRecentErrorMessages() {
|
||||
return _manager.getMostRecentErrorMessages();
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ public interface Transport {
|
||||
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException;
|
||||
public short getReachabilityStatus();
|
||||
public void recheckReachability();
|
||||
public boolean isBacklogged(Hash dest);
|
||||
|
||||
public boolean isUnreachable(Hash peer);
|
||||
}
|
||||
|
@ -382,6 +382,7 @@ public abstract class TransportImpl implements Transport {
|
||||
public RouterContext getContext() { return _context; }
|
||||
public short getReachabilityStatus() { return CommSystemFacade.STATUS_UNKNOWN; }
|
||||
public void recheckReachability() {}
|
||||
public boolean isBacklogged(Hash dest) { return false; }
|
||||
|
||||
private static final long UNREACHABLE_PERIOD = 5*60*1000;
|
||||
public boolean isUnreachable(Hash peer) {
|
||||
|
@ -193,7 +193,14 @@ public class TransportManager implements TransportEventListener {
|
||||
((Transport)_transports.get(i)).recheckReachability();
|
||||
}
|
||||
|
||||
|
||||
public boolean isBacklogged(Hash dest) {
|
||||
for (int i = 0; i < _transports.size(); i++) {
|
||||
Transport t = (Transport)_transports.get(i);
|
||||
if (t.isBacklogged(dest))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Map getAddresses() {
|
||||
Map rv = new HashMap(_transports.size());
|
||||
|
@ -304,7 +304,7 @@ public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {
|
||||
}
|
||||
return queueTime;
|
||||
}
|
||||
private boolean tooBacklogged() {
|
||||
public boolean tooBacklogged() {
|
||||
long queueTime = queueTime();
|
||||
if (queueTime <= 0) return false;
|
||||
int size = 0;
|
||||
|
@ -311,6 +311,13 @@ public class NTCPTransport extends TransportImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBacklogged(Hash dest) {
|
||||
synchronized (_conLock) {
|
||||
NTCPConnection con = (NTCPConnection)_conByIdent.get(dest);
|
||||
return (con != null) && con.isEstablished() && con.tooBacklogged();
|
||||
}
|
||||
}
|
||||
|
||||
void removeCon(NTCPConnection con) {
|
||||
NTCPConnection removed = null;
|
||||
synchronized (_conLock) {
|
||||
@ -541,82 +548,85 @@ public class NTCPTransport extends TransportImpl {
|
||||
StringBuffer buf = new StringBuffer(512);
|
||||
buf.append("<b id=\"ntcpcon\">NTCP connections: ").append(peers.size()).append("</b><br />\n");
|
||||
buf.append("<table border=\"1\">\n");
|
||||
buf.append(" <tr><td><b>peer</b></td>");
|
||||
buf.append(" <tr><td><b><a href=\"#def.peer\">peer</a></b></td>");
|
||||
buf.append(" <td><b>dir</b></td>");
|
||||
buf.append(" <td><b>uptime</b></td>");
|
||||
buf.append(" <td><b>idle</b></td>");
|
||||
buf.append(" <td><b>sent</b></td>");
|
||||
buf.append(" <td><b>received</b></td>");
|
||||
buf.append(" <td><b>out/in</b></td>");
|
||||
buf.append(" <td align=\"right\"><b><a href=\"#def.idle\">idle</a></b></td>");
|
||||
buf.append(" <td align=\"right\"><b><a href=\"#def.rate\">in/out</a></b></td>");
|
||||
buf.append(" <td align=\"right\"><b><a href=\"#def.up\">up</a></b></td>");
|
||||
buf.append(" <td align=\"right\"><b><a href=\"#def.skew\">skew</a></b></td>");
|
||||
buf.append(" <td align=\"right\"><b><a href=\"#def.send\">send</a></b></td>");
|
||||
buf.append(" <td align=\"right\"><b><a href=\"#def.recv\">recv</a></b></td>");
|
||||
buf.append(" <td><b>out queue</b></td>");
|
||||
buf.append(" <td><b>backlogged?</b></td>");
|
||||
buf.append(" <td><b>reading?</b></td>");
|
||||
buf.append(" <td><b>skew</b></td>");
|
||||
buf.append(" </tr>\n");
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
for (Iterator iter = peers.iterator(); iter.hasNext(); ) {
|
||||
NTCPConnection con = (NTCPConnection)iter.next();
|
||||
buf.append("<tr><td>").append(con.getRemotePeer().calculateHash().toBase64().substring(0,8));
|
||||
buf.append("</td><td>");
|
||||
String name = con.getRemotePeer().calculateHash().toBase64().substring(0,6);
|
||||
buf.append("<tr><td><code><a href=\"netdb.jsp#").append(name).append("\">").append(name);
|
||||
buf.append("</code></td><td align=\"center\"><code>");
|
||||
if (con.getIsInbound())
|
||||
buf.append("in");
|
||||
else
|
||||
buf.append("out");
|
||||
buf.append("</td><td>").append(DataHelper.formatDuration(con.getUptime()));
|
||||
totalUptime += con.getUptime();
|
||||
buf.append("</td><td>").append(con.getTimeSinceSend()/1000);
|
||||
buf.append("s/").append(con.getTimeSinceReceive()/1000);
|
||||
buf.append("s</td><td>").append(con.getMessagesSent());
|
||||
totalSend += con.getMessagesSent();
|
||||
buf.append("</td><td>").append(con.getMessagesReceived());
|
||||
totalRecv += con.getMessagesReceived();
|
||||
buf.append("</td><td>");
|
||||
if (con.getTimeSinceSend() < 10*1000) {
|
||||
buf.append(formatRate(con.getSendRate()/1024));
|
||||
bpsSend += con.getSendRate();
|
||||
} else {
|
||||
buf.append(formatRate(0));
|
||||
}
|
||||
buf.append("/");
|
||||
buf.append("</code></td><td align=\"right\"><code>");
|
||||
buf.append(con.getTimeSinceReceive()/1000);
|
||||
buf.append("s/").append(con.getTimeSinceSend()/1000);
|
||||
buf.append("s</code></td><td align=\"right\"><code>");
|
||||
if (con.getTimeSinceReceive() < 10*1000) {
|
||||
buf.append(formatRate(con.getRecvRate()/1024));
|
||||
bpsRecv += con.getRecvRate();
|
||||
} else {
|
||||
buf.append(formatRate(0));
|
||||
}
|
||||
buf.append("/");
|
||||
if (con.getTimeSinceSend() < 10*1000) {
|
||||
buf.append(formatRate(con.getSendRate()/1024));
|
||||
bpsSend += con.getSendRate();
|
||||
} else {
|
||||
buf.append(formatRate(0));
|
||||
}
|
||||
buf.append("KBps");
|
||||
buf.append("</code></td><td align=\"right\"><code>").append(DataHelper.formatDuration(con.getUptime()));
|
||||
totalUptime += con.getUptime();
|
||||
offsetTotal = offsetTotal + con.getClockSkew();
|
||||
buf.append("</code></td><td align=\"right\"><code>").append(con.getClockSkew());
|
||||
buf.append("s</code></td><td align=\"right\"><code>").append(con.getMessagesSent());
|
||||
totalSend += con.getMessagesSent();
|
||||
buf.append("</code></td><td align=\"right\"><code>").append(con.getMessagesReceived());
|
||||
totalRecv += con.getMessagesReceived();
|
||||
long outQueue = con.getOutboundQueueSize();
|
||||
if (outQueue <= 0) {
|
||||
buf.append("</td><td>No messages");
|
||||
buf.append("</code></td><td align=\"right\"><code>No messages");
|
||||
} else {
|
||||
buf.append("</td><td>").append(outQueue).append(" message");
|
||||
buf.append("</code></td><td align=\"right\"><code>").append(outQueue).append(" message");
|
||||
if (outQueue > 1)
|
||||
buf.append("s");
|
||||
writingPeers++;
|
||||
}
|
||||
buf.append("</td><td>").append(con.getConsecutiveBacklog() > 0 ? "true" : "false");
|
||||
buf.append("</code></td><td align=\"center\"><code>").append(con.getConsecutiveBacklog() > 0 ? "true" : "false");
|
||||
long readTime = con.getReadTime();
|
||||
if (readTime <= 0) {
|
||||
buf.append("</td><td>No");
|
||||
buf.append("</code></td><td align=\"center\"><code>No");
|
||||
} else {
|
||||
buf.append("</td><td>For ").append(DataHelper.formatDuration(readTime));
|
||||
buf.append("</code></td><td><code>For ").append(DataHelper.formatDuration(readTime));
|
||||
readingPeers++;
|
||||
}
|
||||
offsetTotal = offsetTotal + con.getClockSkew();
|
||||
buf.append("</td><td>").append(con.getClockSkew());
|
||||
buf.append("s</td></tr>\n");
|
||||
buf.append("</code></td></tr>\n");
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
|
||||
if (peers.size() > 0) {
|
||||
buf.append("<tr><td colspan=\"11\"><hr /></td></tr>\n");
|
||||
buf.append("<tr><td>").append(peers.size()).append(" peers</td><td> </td><td>").append(DataHelper.formatDuration(totalUptime/peers.size()));
|
||||
buf.append("</td><td> </td><td>").append(totalSend).append("</td><td>").append(totalRecv);
|
||||
buf.append("</td><td>").append(formatRate(bpsSend/1024)).append("/").append(formatRate(bpsRecv/1024)).append("KBps");
|
||||
buf.append("<tr><td>").append(peers.size()).append(" peers</td><td> </td><td> ");
|
||||
buf.append("</td><td align=\"right\">").append(formatRate(bpsRecv/1024)).append("/").append(formatRate(bpsSend/1024)).append("KBps");
|
||||
buf.append("</td><td align=\"right\">").append(DataHelper.formatDuration(totalUptime/peers.size()));
|
||||
buf.append("</td><td align=\"right\">").append(peers.size() > 0 ? DataHelper.formatDuration(offsetTotal*1000/peers.size()) : "0ms");
|
||||
buf.append("</td><td align=\"right\">").append(totalSend).append("</td><td align=\"right\">").append(totalRecv);
|
||||
buf.append("</td><td> </td><td> </td><td> ");
|
||||
buf.append("</td><td>").append(peers.size() > 0 ? DataHelper.formatDuration(offsetTotal*1000/peers.size()) : "0ms");
|
||||
buf.append("</td></tr>\n");
|
||||
}
|
||||
|
||||
@ -627,7 +637,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
buf.setLength(0);
|
||||
}
|
||||
|
||||
private static NumberFormat _rateFmt = new DecimalFormat("#,#00.00");
|
||||
private static NumberFormat _rateFmt = new DecimalFormat("#,#0.00");
|
||||
private static String formatRate(float rate) {
|
||||
synchronized (_rateFmt) { return _rateFmt.format(rate); }
|
||||
}
|
||||
@ -661,7 +671,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
}
|
||||
protected int compare(NTCPConnection l, NTCPConnection r) {
|
||||
// base64 retains binary ordering
|
||||
return DataHelper.compareTo(l.getRemotePeer().calculateHash().getData(), r.getRemotePeer().calculateHash().getData());
|
||||
return l.getRemotePeer().calculateHash().toBase64().compareTo(r.getRemotePeer().calculateHash().toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1356,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
private static final IdleInComparator _instance = new IdleInComparator();
|
||||
public static final IdleInComparator instance() { return _instance; }
|
||||
protected int compare(PeerState l, PeerState r) {
|
||||
long rv = l.getLastReceiveTime() - r.getLastReceiveTime();
|
||||
long rv = r.getLastReceiveTime() - l.getLastReceiveTime();
|
||||
if (rv == 0) // fallback on alpha
|
||||
return super.compare(l, r);
|
||||
else
|
||||
@ -1367,7 +1367,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
private static final IdleOutComparator _instance = new IdleOutComparator();
|
||||
public static final IdleOutComparator instance() { return _instance; }
|
||||
protected int compare(PeerState l, PeerState r) {
|
||||
long rv = l.getLastSendTime() - r.getLastSendTime();
|
||||
long rv = r.getLastSendTime() - l.getLastSendTime();
|
||||
if (rv == 0) // fallback on alpha
|
||||
return super.compare(l, r);
|
||||
else
|
||||
@ -1400,7 +1400,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
private static final UptimeComparator _instance = new UptimeComparator();
|
||||
public static final UptimeComparator instance() { return _instance; }
|
||||
protected int compare(PeerState l, PeerState r) {
|
||||
long rv = l.getKeyEstablishedTime() - r.getKeyEstablishedTime();
|
||||
long rv = r.getKeyEstablishedTime() - l.getKeyEstablishedTime();
|
||||
if (rv == 0) // fallback on alpha
|
||||
return super.compare(l, r);
|
||||
else
|
||||
@ -1537,7 +1537,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
}
|
||||
protected int compare(PeerState l, PeerState r) {
|
||||
// base64 retains binary ordering
|
||||
return DataHelper.compareTo(l.getRemotePeer().getData(), r.getRemotePeer().getData());
|
||||
return l.getRemotePeer().toBase64().compareTo(r.getRemotePeer().toBase64());
|
||||
}
|
||||
}
|
||||
private static class InverseComparator implements Comparator {
|
||||
@ -1646,7 +1646,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
buf.append("<a href=\"netdb.jsp#");
|
||||
buf.append(name);
|
||||
buf.append("\">");
|
||||
buf.append(name).append("@");
|
||||
buf.append(name);
|
||||
/*
|
||||
buf.append("@");
|
||||
byte ip[] = peer.getRemoteIP();
|
||||
for (int j = 0; j < ip.length; j++) {
|
||||
int num = ip[j] & 0xFF;
|
||||
@ -1669,7 +1671,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
else if (port < 10000)
|
||||
buf.append("0");
|
||||
buf.append(port);
|
||||
buf.append("</a>");
|
||||
*/
|
||||
buf.append("</a> ");
|
||||
if (peer.getWeRelayToThemAs() > 0)
|
||||
buf.append(">");
|
||||
else
|
||||
@ -1702,7 +1705,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (idleIn < 0) idleIn = 0;
|
||||
if (idleOut < 0) idleOut = 0;
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(idleIn);
|
||||
buf.append("s/");
|
||||
buf.append(idleOut);
|
||||
@ -1711,9 +1714,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
int recvBps = (idleIn > 2 ? 0 : peer.getReceiveBps());
|
||||
int sendBps = (idleOut > 2 ? 0 : peer.getSendBps());
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(formatKBps(recvBps));
|
||||
buf.append("KBps/");
|
||||
buf.append("/");
|
||||
buf.append(formatKBps(sendBps));
|
||||
buf.append("KBps ");
|
||||
//buf.append(formatKBps(peer.getReceiveACKBps()));
|
||||
@ -1724,18 +1727,18 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
|
||||
long uptime = now - peer.getKeyEstablishedTime();
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(DataHelper.formatDuration(uptime));
|
||||
buf.append("</code></td>");
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(peer.getClockSkew());
|
||||
buf.append("s</code></td>");
|
||||
offsetTotal = offsetTotal + peer.getClockSkew();
|
||||
|
||||
long sendWindow = peer.getSendWindowBytes();
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(sendWindow/1024);
|
||||
buf.append("K");
|
||||
buf.append("/").append(peer.getConcurrentSends());
|
||||
@ -1743,26 +1746,26 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
buf.append("/").append(peer.getConsecutiveSendRejections());
|
||||
buf.append("</code></td>");
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(peer.getSlowStartThreshold()/1024);
|
||||
buf.append("K</code></td>");
|
||||
|
||||
int rtt = peer.getRTT();
|
||||
int rto = peer.getRTO();
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(rtt);
|
||||
buf.append("</code></td>");
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(peer.getRTTDeviation());
|
||||
buf.append("</code></td>");
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(rto);
|
||||
buf.append("</code></td>");
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(peer.getMTU()).append("/").append(peer.getReceiveMTU());
|
||||
|
||||
//.append('/');
|
||||
@ -1773,11 +1776,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
long sent = peer.getPacketsTransmitted();
|
||||
long recv = peer.getPacketsReceived();
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(sent);
|
||||
buf.append("</code></td>");
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(recv);
|
||||
buf.append("</code></td>");
|
||||
|
||||
@ -1789,14 +1792,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
long resent = peer.getPacketsRetransmitted();
|
||||
long dupRecv = peer.getPacketsReceivedDuplicate();
|
||||
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
//buf.append(formatPct(sendLostPct));
|
||||
buf.append(resent); // + "/" + peer.getPacketsPeriodRetransmitted() + "/" + sent);
|
||||
//buf.append(peer.getPacketRetransmissionRate());
|
||||
buf.append("</code></td>");
|
||||
|
||||
double recvDupPct = (double)peer.getPacketsReceivedDuplicate()/(double)peer.getPacketsReceived();
|
||||
buf.append("<td valign=\"top\" ><code>");
|
||||
buf.append("<td valign=\"top\" align=\"right\" ><code>");
|
||||
buf.append(dupRecv); //formatPct(recvDupPct));
|
||||
buf.append("</code></td>");
|
||||
|
||||
@ -1822,22 +1825,22 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
|
||||
buf.append("<tr><td colspan=\"15\"><hr /></td></tr>\n");
|
||||
buf.append(" <tr><td colspan=\"2\"><b>Total</b></td>");
|
||||
buf.append(" <td>");
|
||||
buf.append(formatKBps(bpsIn)).append("KBps/").append(formatKBps(bpsOut));
|
||||
buf.append(" <td align=\"right\">");
|
||||
buf.append(formatKBps(bpsIn)).append("/").append(formatKBps(bpsOut));
|
||||
buf.append("KBps</td>");
|
||||
buf.append(" <td>").append(numPeers > 0 ? DataHelper.formatDuration(uptimeMsTotal/numPeers) : "0s");
|
||||
buf.append("</td><td>").append(numPeers > 0 ? DataHelper.formatDuration(offsetTotal*1000/numPeers) : "0ms").append("</td>\n");
|
||||
buf.append(" <td>");
|
||||
buf.append(" <td align=\"right\">").append(numPeers > 0 ? DataHelper.formatDuration(uptimeMsTotal/numPeers) : "0s");
|
||||
buf.append("</td><td align=\"right\">").append(numPeers > 0 ? DataHelper.formatDuration(offsetTotal*1000/numPeers) : "0ms").append("</td>\n");
|
||||
buf.append(" <td align=\"right\">");
|
||||
buf.append(numPeers > 0 ? cwinTotal/(numPeers*1024) + "K" : "0K");
|
||||
buf.append("</td><td> </td>\n");
|
||||
buf.append(" <td>");
|
||||
buf.append(" <td align=\"right\">");
|
||||
buf.append(numPeers > 0 ? rttTotal/numPeers : 0);
|
||||
buf.append("</td><td> </td><td>");
|
||||
buf.append("</td><td align=\"right\"> </td><td align=\"right\">");
|
||||
buf.append(numPeers > 0 ? rtoTotal/numPeers : 0);
|
||||
buf.append("</td>\n <td> </td><td>");
|
||||
buf.append(sendTotal).append("</td><td>").append(recvTotal).append("</td>\n");
|
||||
buf.append(" <td>").append(resentTotal);
|
||||
buf.append("</td><td>").append(dupRecvTotal).append("</td>\n");
|
||||
buf.append("</td>\n <td> </td><td align=\"right\">");
|
||||
buf.append(sendTotal).append("</td><td align=\"right\">").append(recvTotal).append("</td>\n");
|
||||
buf.append(" <td align=\"right\">").append(resentTotal);
|
||||
buf.append("</td><td align=\"right\">").append(dupRecvTotal).append("</td>\n");
|
||||
buf.append(" </tr>\n");
|
||||
buf.append("<tr><td colspan=\"15\" valign=\"top\" align=\"left\">");
|
||||
long bytesTransmitted = _context.bandwidthLimiter().getTotalAllocatedOutboundBytes();
|
||||
|
@ -14,8 +14,8 @@ import net.i2p.util.Log;
|
||||
public class PooledTunnelCreatorConfig extends TunnelCreatorConfig {
|
||||
private TunnelPool _pool;
|
||||
private TestJob _testJob;
|
||||
private Job _expireJob;
|
||||
private TunnelInfo _pairedTunnel;
|
||||
// private Job _expireJob;
|
||||
// private TunnelInfo _pairedTunnel;
|
||||
private boolean _live;
|
||||
|
||||
/** Creates a new instance of PooledTunnelCreatorConfig */
|
||||
@ -68,8 +68,9 @@ public class PooledTunnelCreatorConfig extends TunnelCreatorConfig {
|
||||
public TunnelPool getTunnelPool() { return _pool; }
|
||||
|
||||
public void setTestJob(TestJob job) { _testJob = job; }
|
||||
public void setExpireJob(Job job) { _expireJob = job; }
|
||||
public void setExpireJob(Job job) { /* _expireJob = job; */ }
|
||||
|
||||
public void setPairedTunnel(TunnelInfo tunnel) { _pairedTunnel = tunnel; }
|
||||
public TunnelInfo getPairedTunnel() { return _pairedTunnel; }
|
||||
// Fix memory leaks caused by references if you need to use pairedTunnel
|
||||
public void setPairedTunnel(TunnelInfo tunnel) { /* _pairedTunnel = tunnel; */}
|
||||
// public TunnelInfo getPairedTunnel() { return _pairedTunnel; }
|
||||
}
|
||||
|
@ -187,6 +187,19 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isValidTunnel(Hash client, TunnelInfo tunnel) {
|
||||
if (tunnel.getExpiration() < _context.clock().now())
|
||||
return false;
|
||||
TunnelPool pool;
|
||||
if (tunnel.isInbound())
|
||||
pool = (TunnelPool)_clientInboundPools.get(client);
|
||||
else
|
||||
pool = (TunnelPool)_clientOutboundPools.get(client);
|
||||
if (pool == null)
|
||||
return false;
|
||||
return pool.listTunnels().contains(tunnel);
|
||||
}
|
||||
|
||||
public TunnelPoolSettings getInboundSettings() { return _inboundExploratory.getSettings(); }
|
||||
public TunnelPoolSettings getOutboundSettings() { return _outboundExploratory.getSettings(); }
|
||||
public void setInboundSettings(TunnelPoolSettings settings) { _inboundExploratory.setSettings(settings); }
|
||||
@ -498,7 +511,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
String cap = getCapacity(peer);
|
||||
TunnelId id = (info.isInbound() ? info.getReceiveTunnelId(j) : info.getSendTunnelId(j));
|
||||
if (_context.routerHash().equals(peer))
|
||||
out.write("<td><i>" + peer.toBase64().substring(0,4) + (id == null ? "" : ":" + id) + "</i>" + cap + "</td>");
|
||||
out.write("<td>" + (id == null ? "" : "" + id) + "</td>");
|
||||
else
|
||||
out.write("<td>" + peer.toBase64().substring(0,4) + (id == null ? "" : ":" + id) + cap + "</td>");
|
||||
}
|
||||
|
Reference in New Issue
Block a user