Compare commits

...

13 Commits

Author SHA1 Message Date
f67f47f0cd 0.6.1.30 2007-10-08 03:09:35 +00:00
5ad6ee60eb 0.6.1.30 2007-10-08 03:01:47 +00:00
5accba6cdc 2007-10-07 Complication
* Fix an issue in EepGet whereby sending of "etag" and "lastModified" headers
      broke retrying.
2007-10-08 02:36:17 +00:00
zzz
313e1704df 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-27 03:52:32 +00:00
zzz
cf4d2b17c9 2007-09-22 zzz
* Send messages for the same destination out the same outbound
      tunnel to reduce out-of-order delivery.
2007-09-23 02:44:34 +00:00
zzz
9145eedc35 2007-09-19 zzz
* i2psnark: Fix broken multifile torrent Delete;
        cleanup Storage resources in AddTorrent;
        don't autostart torrent after Create
2007-09-20 01:44:02 +00:00
zzz
b772179077 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-18 19:09:19 +00:00
zzz
9054a196ce 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-15 01:58:30 +00:00
zzz
d28a96ac7d 2007-09-09 zzz
* eepget: Add support for Last-Modified and If-Modified-Since
    * addressbook: Finish incomplete support for Last-Modified
2007-09-09 17:38:53 +00:00
zzz
9c73f80ac3 (zzz) Copy over SocketTimeout.java file from syndie for EepGet.java 2007-09-08 20:21:15 +00:00
20c46cff04 synced up with the eepget from the syndie source tree (allowing better
control of timeouts and transparent redirection).  the users of eepget
in this source tree don't necessarily use the timeout controls, though
they can be updated to do so
2007-09-08 02:24:01 +00:00
f332513755 added trevorreznik.i2p 2007-09-02 01:36:54 +00:00
zzz
cb69a66498 (zzz) .29 announcement 2007-08-24 02:34:40 +00:00
36 changed files with 636 additions and 219 deletions

View File

@ -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) {

View File

@ -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--;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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())

View File

@ -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();

View File

@ -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());

View File

@ -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("/");

View File

@ -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;
}
}
}

View File

@ -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) {}
}

View File

@ -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
/**

View File

@ -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() {

View File

@ -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() {

View File

@ -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);

View File

@ -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;
}

View File

@ -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) {}
}

View 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();
}
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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>

View File

@ -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>.

View File

@ -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" />
&#149;
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 />
&#149;
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 />
&#149;
2007-04-10:

View File

@ -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

View File

@ -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);

View File

@ -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; }

View File

@ -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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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());

View File

@ -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;

View File

@ -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>&nbsp;</td><td>").append(DataHelper.formatDuration(totalUptime/peers.size()));
buf.append("</td><td>&nbsp;</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>&nbsp;</td><td>&nbsp;");
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>&nbsp;</td><td>&nbsp;</td><td>&nbsp;");
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());
}
}

View File

@ -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>&nbsp;");
if (peer.getWeRelayToThemAs() > 0)
buf.append("&gt;");
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>&nbsp;</td>\n");
buf.append(" <td>");
buf.append(" <td align=\"right\">");
buf.append(numPeers > 0 ? rttTotal/numPeers : 0);
buf.append("</td><td>&nbsp;</td><td>");
buf.append("</td><td align=\"right\">&nbsp;</td><td align=\"right\">");
buf.append(numPeers > 0 ? rtoTotal/numPeers : 0);
buf.append("</td>\n <td>&nbsp;</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>&nbsp;</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();

View File

@ -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; }
}

View File

@ -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>");
}