forked from I2P_Developers/i2p.i2p
* ExploratoryPeerSelector:
- Exclude floodfill peers - Tweak the HighCap vs. NonFailing decision * i2psnark: Increase retries for .torrent fetch * IRC Proxy: Prevent mIRC from sending an alternate DCC request containing an IP * readme.html: Reorder some items * Stats: Add some more required stats * Streaming lib: Fix slow start to be exponential growth, fix congestion avoidance to be linear growth. Should speed up local connections a lot, and remote connections a little.
This commit is contained in:
@ -160,8 +160,10 @@ public class I2PSnarkUtil {
|
|||||||
/**
|
/**
|
||||||
* fetch the given URL, returning the file it is stored in, or null on error
|
* fetch the given URL, returning the file it is stored in, or null on error
|
||||||
*/
|
*/
|
||||||
public File get(String url) { return get(url, true); }
|
public File get(String url) { return get(url, true, 1); }
|
||||||
public File get(String url, boolean rewrite) {
|
public File get(String url, boolean rewrite) { return get(url, rewrite, 1); }
|
||||||
|
public File get(String url, int retries) { return get(url, true, retries); }
|
||||||
|
public File get(String url, boolean rewrite, int retries) {
|
||||||
_log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
|
_log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
|
||||||
File out = null;
|
File out = null;
|
||||||
try {
|
try {
|
||||||
@ -175,7 +177,7 @@ public class I2PSnarkUtil {
|
|||||||
if (rewrite)
|
if (rewrite)
|
||||||
fetchURL = rewriteAnnounce(url);
|
fetchURL = rewriteAnnounce(url);
|
||||||
//_log.debug("Rewritten url [" + fetchURL + "]");
|
//_log.debug("Rewritten url [" + fetchURL + "]");
|
||||||
EepGet get = new EepGet(_context, _shouldProxy, _proxyHost, _proxyPort, 1, out.getAbsolutePath(), fetchURL);
|
EepGet get = new EepGet(_context, _shouldProxy, _proxyHost, _proxyPort, retries, out.getAbsolutePath(), fetchURL);
|
||||||
if (get.fetch()) {
|
if (get.fetch()) {
|
||||||
_log.debug("Fetch successful [" + url + "]: size=" + out.length());
|
_log.debug("Fetch successful [" + url + "]: size=" + out.length());
|
||||||
return out;
|
return out;
|
||||||
|
@ -312,7 +312,7 @@ public class Snark
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
activity = "Getting torrent";
|
activity = "Getting torrent";
|
||||||
File torrentFile = I2PSnarkUtil.instance().get(torrent);
|
File torrentFile = I2PSnarkUtil.instance().get(torrent, 3);
|
||||||
if (torrentFile == null) {
|
if (torrentFile == null) {
|
||||||
fatal("Unable to fetch " + torrent);
|
fatal("Unable to fetch " + torrent);
|
||||||
if (false) return; // never reached - fatal(..) throws
|
if (false) return; // never reached - fatal(..) throws
|
||||||
|
@ -435,6 +435,16 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mIRC sends "NOTICE user :DCC Send file (IP)"
|
||||||
|
// in addition to the CTCP version
|
||||||
|
if("NOTICE".equalsIgnoreCase(command))
|
||||||
|
{
|
||||||
|
String msg = field[2];
|
||||||
|
if(msg.startsWith(":DCC "))
|
||||||
|
return null;
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
|
|
||||||
// Allow PRIVMSG, but block CTCP (except ACTION).
|
// Allow PRIVMSG, but block CTCP (except ACTION).
|
||||||
if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
|
if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
|
||||||
{
|
{
|
||||||
|
@ -302,24 +302,35 @@ public class ConnectionPacketHandler {
|
|||||||
_context.statManager().addRateData("stream.trend", trend, newWindowSize);
|
_context.statManager().addRateData("stream.trend", trend, newWindowSize);
|
||||||
|
|
||||||
if ( (!congested) && (acked > 0) && (numResends <= 0) ) {
|
if ( (!congested) && (acked > 0) && (numResends <= 0) ) {
|
||||||
if (trend < 0) {
|
if (newWindowSize < con.getLastCongestionSeenAt() / 2) {
|
||||||
|
// Don't make this <= LastCongestion/2 or we'll jump right back to where we were
|
||||||
|
// slow start - exponential growth
|
||||||
|
// grow acked/N times (where N = the slow start factor)
|
||||||
|
// always grow at least 1
|
||||||
|
int factor = con.getOptions().getSlowStartGrowthRateFactor();
|
||||||
|
if (factor <= 1)
|
||||||
|
newWindowSize += acked;
|
||||||
|
else if (acked < factor)
|
||||||
|
newWindowSize++;
|
||||||
|
else
|
||||||
|
newWindowSize += acked / factor;
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("slow start acks = " + acked + " for " + con);
|
||||||
|
} else if (trend < 0) {
|
||||||
// rtt is shrinking, so lets increment the cwin
|
// rtt is shrinking, so lets increment the cwin
|
||||||
newWindowSize++;
|
newWindowSize++;
|
||||||
} else if (newWindowSize > con.getLastCongestionSeenAt() / 2) {
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("trend < 0 for " + con);
|
||||||
|
} else {
|
||||||
// congestion avoidance
|
// congestion avoidance
|
||||||
|
// linear growth - increase window 1/N per RTT
|
||||||
// we can't use newWindowSize += 1/newWindowSize, since we're
|
// we can't use newWindowSize += acked/(oldWindow*N) (where N = the cong. avoid. factor), since we're
|
||||||
// integers, so lets use a random distribution instead
|
// integers, so lets use a random distribution instead
|
||||||
int shouldIncrement = _context.random().nextInt(con.getOptions().getCongestionAvoidanceGrowthRateFactor()*newWindowSize);
|
int shouldIncrement = _context.random().nextInt(con.getOptions().getCongestionAvoidanceGrowthRateFactor()*newWindowSize);
|
||||||
if (shouldIncrement <= 0)
|
if (shouldIncrement < acked)
|
||||||
newWindowSize += 1;
|
|
||||||
} else {
|
|
||||||
// slow start, but modified to take into account the fact
|
|
||||||
// that windows in the streaming lib are messages, not bytes,
|
|
||||||
// so we only grow 1 every N times (where N = the slow start factor)
|
|
||||||
int shouldIncrement = _context.random().nextInt(con.getOptions().getSlowStartGrowthRateFactor());
|
|
||||||
if (shouldIncrement <= 0)
|
|
||||||
newWindowSize += 1;
|
newWindowSize += 1;
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("cong. avoid acks = " + acked + " for " + con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,9 @@ public class StatManager {
|
|||||||
"bw.recvRate,bw.sendBps,bw.sendRate,client.sendAckTime,clock.skew,crypto.elGamal.encrypt," +
|
"bw.recvRate,bw.sendBps,bw.sendRate,client.sendAckTime,clock.skew,crypto.elGamal.encrypt," +
|
||||||
"jobQueue.jobLag,netDb.successTime,router.fastPeers," +
|
"jobQueue.jobLag,netDb.successTime,router.fastPeers," +
|
||||||
"transport.receiveMessageSize,transport.sendMessageSize,transport.sendProcessingTime," +
|
"transport.receiveMessageSize,transport.sendMessageSize,transport.sendProcessingTime," +
|
||||||
|
"tunnel.acceptLoad,tunnel.buildRequestTime,tunnel.rejectOverloaded,tunnel.rejectTimeout" +
|
||||||
|
"tunnel.buildClientExpire,tunnel.buildClientReject,tunnel.buildClientSuccess," +
|
||||||
|
"tunnel.buildExploratoryExpire,tunnel.buildExploratoryReject,tunnel.buildExploratorySuccess," +
|
||||||
"tunnel.buildRatio.*,tunnel.buildFailure,tunnel.buildSuccess,tunnel.corruptMessage," +
|
"tunnel.buildRatio.*,tunnel.buildFailure,tunnel.buildSuccess,tunnel.corruptMessage," +
|
||||||
"tunnel.decryptRequestTime,tunnel.fragmentedDropped,tunnel.participatingMessageCount,"+
|
"tunnel.decryptRequestTime,tunnel.fragmentedDropped,tunnel.participatingMessageCount,"+
|
||||||
"tunnel.participatingTunnels,tunnel.testFailedTime,tunnel.testSuccessTime" ;
|
"tunnel.participatingTunnels,tunnel.testFailedTime,tunnel.testSuccessTime" ;
|
||||||
|
16
history.txt
16
history.txt
@ -1,3 +1,17 @@
|
|||||||
|
2008-03-19 zzz
|
||||||
|
* ExploratoryPeerSelector:
|
||||||
|
- Exclude floodfill peers
|
||||||
|
- Tweak the HighCap vs. NonFailing decision
|
||||||
|
* i2psnark: Increase retries for .torrent fetch
|
||||||
|
* IRC Proxy: Prevent mIRC from sending an alternate DCC request
|
||||||
|
containing an IP
|
||||||
|
* readme.html: Reorder some items
|
||||||
|
* Stats: Add some more required stats
|
||||||
|
* Streaming lib: Fix slow start to be exponential growth,
|
||||||
|
fix congestion avoidance to be linear growth.
|
||||||
|
Should speed up local connections a lot, and remote
|
||||||
|
connections a little.
|
||||||
|
|
||||||
2008-03-14 zzz
|
2008-03-14 zzz
|
||||||
* Floodfill Search:
|
* Floodfill Search:
|
||||||
- Prefer heard-from, unfailing, unshitlisted floodfill peers
|
- Prefer heard-from, unfailing, unshitlisted floodfill peers
|
||||||
@ -45,7 +59,7 @@
|
|||||||
* NetDb: Comment out published netDb stats disabled for .32
|
* NetDb: Comment out published netDb stats disabled for .32
|
||||||
|
|
||||||
2008-03-08 zzz
|
2008-03-08 zzz
|
||||||
* ClientPeerSelector: Implement strict ordering of peers,
|
* TunnelPeerSelectors: Implement strict ordering of peers,
|
||||||
based on XOR distance from a random hash
|
based on XOR distance from a random hash
|
||||||
separately generated for each tunnel pool
|
separately generated for each tunnel pool
|
||||||
|
|
||||||
|
10
readme.html
10
readme.html
@ -3,10 +3,6 @@ grow over the next few minutes and you'll see a "shared clients" local destinati
|
|||||||
on the left (if not, <a href="#trouble">see below</a>). Once those show up,
|
on the left (if not, <a href="#trouble">see below</a>). Once those show up,
|
||||||
you can:</p>
|
you can:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>blog anonymously</b> - check out <a href="http://syndie.i2p2.de/">Syndie</a></li>
|
|
||||||
<li><b>chat anonymously</b> - fire up your own IRC client and connect to the
|
|
||||||
server at <b>localhost port 6668</b>. This points at one of two anonymously hosted
|
|
||||||
IRC servers, but neither you nor they know where the other is.</li>
|
|
||||||
<li><b>browse "eepsites"</b> - on I2P there are anonymously hosted websites -
|
<li><b>browse "eepsites"</b> - on I2P there are anonymously hosted websites -
|
||||||
tell your browser to use the <b>HTTP proxy at localhost port 4444</b>, then
|
tell your browser to use the <b>HTTP proxy at localhost port 4444</b>, then
|
||||||
browse to an eepsite -
|
browse to an eepsite -
|
||||||
@ -32,8 +28,12 @@ you can:</p>
|
|||||||
<li><b>use anonymous email</b> - postman has created a mail system compatible with normal mail
|
<li><b>use anonymous email</b> - postman has created a mail system compatible with normal mail
|
||||||
clients (POP3 / SMTP) that allows email within I2P as well as mail from and to the normal
|
clients (POP3 / SMTP) that allows email within I2P as well as mail from and to the normal
|
||||||
internet! get your account at <a href="http://hq.postman.i2p/">hq.postman.i2p</a>.
|
internet! get your account at <a href="http://hq.postman.i2p/">hq.postman.i2p</a>.
|
||||||
We bundle <a href="http://susi.i2p/">Susi's</a> <a href="/susimail/susimail">susimail</a>,
|
We bundle <a href="/susimail/susimail">susimail</a>,
|
||||||
a web based anonymity-oriented pop3/smtp client configured to access postman's mail services.</li>
|
a web based anonymity-oriented pop3/smtp client configured to access postman's mail services.</li>
|
||||||
|
<li><b>chat anonymously</b> - fire up your own IRC client and connect to the
|
||||||
|
server at <b>localhost port 6668</b>. This points at one of two anonymously hosted
|
||||||
|
IRC servers, but neither you nor they know where the other is.</li>
|
||||||
|
<li><b>blog anonymously</b> - check out <a href="http://syndie.i2p2.de/">Syndie</a></li>
|
||||||
<li>and lots more</li>
|
<li>and lots more</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
|
|||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $";
|
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $";
|
||||||
public final static String VERSION = "0.6.1.32";
|
public final static String VERSION = "0.6.1.32";
|
||||||
public final static long BUILD = 7;
|
public final static long BUILD = 8;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
@ -277,6 +277,9 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
|||||||
|
|
||||||
_lease = (Lease)orderedLeases.get(orderedLeases.firstKey());
|
_lease = (Lease)orderedLeases.get(orderedLeases.firstKey());
|
||||||
} else {
|
} else {
|
||||||
|
// strangely, _lease isn't used anywhere except for log messages - ?!?!??!?!?!
|
||||||
|
// Apparently the outbound endpoint gets to pick the inbound gateway
|
||||||
|
// and this whole function is pointless.
|
||||||
_lease = (Lease)leases.get(0);
|
_lease = (Lease)leases.get(0);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -5,8 +5,8 @@ import net.i2p.router.RouterContext;
|
|||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick peers randomly out of the fast pool, and put them into tunnels in a
|
* Pick peers randomly out of the fast pool, and put them into tunnels
|
||||||
* random order
|
* ordered by XOR distance from a random key.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ClientPeerSelector extends TunnelPeerSelector {
|
class ClientPeerSelector extends TunnelPeerSelector {
|
||||||
|
@ -3,13 +3,14 @@ package net.i2p.router.tunnel.pool;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
|
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||||
import net.i2p.stat.Rate;
|
import net.i2p.stat.Rate;
|
||||||
import net.i2p.stat.RateStat;
|
import net.i2p.stat.RateStat;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick peers randomly out of the not-failing pool, and put them into randomly
|
* Pick peers randomly out of the not-failing pool, and put them into a tunnel
|
||||||
* ordered tunnels.
|
* ordered by XOR distance from a random key.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExploratoryPeerSelector extends TunnelPeerSelector {
|
class ExploratoryPeerSelector extends TunnelPeerSelector {
|
||||||
@ -31,6 +32,9 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
|
|
||||||
Set exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory());
|
Set exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory());
|
||||||
exclude.add(ctx.routerHash());
|
exclude.add(ctx.routerHash());
|
||||||
|
// Don't use ff peers for exploratory tunnels to lessen exposure to netDb searches and stores
|
||||||
|
FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb();
|
||||||
|
exclude.addAll(fac.getFloodfillPeers());
|
||||||
HashSet matches = new HashSet(length);
|
HashSet matches = new HashSet(length);
|
||||||
boolean exploreHighCap = shouldPickHighCap(ctx);
|
boolean exploreHighCap = shouldPickHighCap(ctx);
|
||||||
if (exploreHighCap)
|
if (exploreHighCap)
|
||||||
@ -52,6 +56,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int MIN_NONFAILING_PCT = 25;
|
||||||
private boolean shouldPickHighCap(RouterContext ctx) {
|
private boolean shouldPickHighCap(RouterContext ctx) {
|
||||||
if (Boolean.valueOf(ctx.getProperty("router.exploreHighCapacity", "false")).booleanValue())
|
if (Boolean.valueOf(ctx.getProperty("router.exploreHighCapacity", "false")).booleanValue())
|
||||||
return true;
|
return true;
|
||||||
@ -62,10 +67,27 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
// randomly from the 'not failing' pool. However, if we are having a
|
// randomly from the 'not failing' pool. However, if we are having a
|
||||||
// hard time building exploratory tunnels, lets fall back again on the
|
// hard time building exploratory tunnels, lets fall back again on the
|
||||||
// high capacity peers, at least for a little bit.
|
// high capacity peers, at least for a little bit.
|
||||||
int failPct = getExploratoryFailPercentage(ctx);
|
int failPct;
|
||||||
|
// getEvents() will be 0 for first 10 minutes
|
||||||
|
if (ctx.router().getUptime() <= 11*60*1000) {
|
||||||
|
failPct = 100 - MIN_NONFAILING_PCT;
|
||||||
|
} else {
|
||||||
|
failPct = getExploratoryFailPercentage(ctx);
|
||||||
|
// always try a little, this helps keep the failPct stat accurate too
|
||||||
|
if (failPct > 100 - MIN_NONFAILING_PCT)
|
||||||
|
failPct = 100 - MIN_NONFAILING_PCT;
|
||||||
|
}
|
||||||
|
Log l = ctx.logManager().getLog(getClass());
|
||||||
|
if (l.shouldLog(Log.DEBUG))
|
||||||
|
l.error("Fail pct: " + failPct);
|
||||||
return (failPct >= ctx.random().nextInt(100));
|
return (failPct >= ctx.random().nextInt(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We should really use the difference between the exploratory fail rate
|
||||||
|
// and the client fail rate.
|
||||||
|
// (return 100 * ((Efail - Cfail) / (1 - Cfail)))
|
||||||
|
// Even this isn't the "true" rate for the NonFailingPeers pool, since we
|
||||||
|
// are often building exploratory tunnels using the HighCapacity pool.
|
||||||
private int getExploratoryFailPercentage(RouterContext ctx) {
|
private int getExploratoryFailPercentage(RouterContext ctx) {
|
||||||
int timeout = getEvents(ctx, "tunnel.buildExploratoryExpire", 10*60*1000);
|
int timeout = getEvents(ctx, "tunnel.buildExploratoryExpire", 10*60*1000);
|
||||||
int reject = getEvents(ctx, "tunnel.buildExploratoryReject", 10*60*1000);
|
int reject = getEvents(ctx, "tunnel.buildExploratoryReject", 10*60*1000);
|
||||||
@ -76,6 +98,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return (int)(100 * pct);
|
return (int)(100 * pct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use current + last to get more recent and smoother data
|
||||||
private int getEvents(RouterContext ctx, String stat, long period) {
|
private int getEvents(RouterContext ctx, String stat, long period) {
|
||||||
RateStat rs = ctx.statManager().getRate(stat);
|
RateStat rs = ctx.statManager().getRate(stat);
|
||||||
if (rs == null)
|
if (rs == null)
|
||||||
@ -83,6 +106,6 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
Rate r = rs.getRate(period);
|
Rate r = rs.getRate(period);
|
||||||
if (r == null)
|
if (r == null)
|
||||||
return 0;
|
return 0;
|
||||||
return (int)r.getLastEventCount();
|
return (int) (r.getLastEventCount() + r.getCurrentEventCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user